Skip to content
No description, website, or topics provided.
Branch: master
Clone or download

Build Status GitHub license

NuGet packages

Name Version
Meziantou.Framework NuGet
Meziantou.Framework.CodeDom NuGet
Meziantou.Framework.CommandLine NuGet
Meziantou.Framework.Csv NuGet
Meziantou.Framework.Html NuGet
Meziantou.Framework.RelativeDate NuGet
Meziantou.Framework.Scheduling NuGet
Meziantou.Framework.Templating NuGet
Meziantou.Framework.Templating.Html NuGet
Meziantou.Framework.TypeConverter NuGet
Meziantou.Framework.Versioning NuGet
Meziantou.Framework.Win32.AccessToken NuGet
Meziantou.Framework.Win32.Amsi NuGet
Meziantou.Framework.Win32.ChangeJournal NuGet
Meziantou.Framework.Win32.CredentialManager NuGet
Meziantou.Framework.Win32.Dialogs NuGet
Meziantou.Framework.Win32.Jobs NuGet
Meziantou.Framework.Win32.Lsa NuGet
Meziantou.Framework.Win32.PerceivedType NuGet
Meziantou.Framework.Win32.RestartManager NuGet
Meziantou.Framework.WPF NuGet

How to contribute

If you want to contribute to this repo, please read the contributing guide first.

How to setup your development environment:

  1. Install the latest version of Visual Studio
  2. Install the version of .NET SDK specified in the global.json file. Currently 2.2.101
  3. Use the solution Meziantou.Framework.sln
  4. You can run unit tests using the Test explorer in Visual Studio or the command line dotnet test

You can also use Visual Studio Code but you won't be able to run the WPF samples.



Lots of extensions methods and utilities

// IO Extensions
IOUtilities.MakeRelativePath(root: @"c:\test", path: @"c:\temp\file.txt") // ..\temp\file.txt
IOUtilities.ToValidFileName("tes/t.txt") // tes_x47_t.txt

// String Extensions
"Tést".RemoveDiacritics() // Test

// Throttle / Debounce

// Slugs
Slug.Create("My super blog post") // my-super-blog-post

// And many more extensions/utilities


A universal converter that supports lots of conversion.

ConvertUtilities.ChangeType("42", defaultValue: 0)
ConvertUtilities.ChangeType("Value1, 2", defaultValue: MyEnum.Unknown)


CSV reader and writer.

var reader = new CsvReader(textReader);
reader.HasHeaderRow = true;

CsvRow row;
while((row = (await reader.ReadRowAsync())) != null)
    row[0];        // Get value by index
    row["column1"] // Get value by column name
var writer = new CsvWriter(sw);
await writer.WriteRowAsync("A", "B");
await writer.BeginRowAsync();
await writer.WriteValueAsync("C");
await writer.WriteValueAsync("D");


Recurrence Rule parser, and ICS generator

var rrule = RecurrenceRule.Parse("FREQ=DAILY;COUNT=3");
var startDate = new DateTime(1997, 09, 02, 09, 00, 00);
var occurrences = rrule.GetNextOccurrences(startDate);
// 1997-09-02 09:00
// 1997-09-03 09:00
// 1997-09-04 09:00


Get the perceived type of a file: Text, Audio, Video, Document, Application, etc.

var perceived = Perceived.GetPerceivedType(".avi");
Assert.AreEqual(PerceivedType.Video, perceived.PerceivedType);


CredentialManager.WriteCredential("ApplicationName", "username", "Pa$$w0rd", CredentialPersistence.Session);

var cred = CredentialManager.ReadCredential("ApplicationName");
Assert.AreEqual("username", cred.UserName);
Assert.AreEqual("Pa$$w0rd", cred.Password);



Template template = new Template();
template.Load("Hello <%=Name%>!");
template.AddArgument("Name", typeof(string));

string result = template.Run("Meziantou"); // result= "Hello Meziantou!"


Extensions for Templating to support the html format: Encoding text, url or attribute. For email, it extracts the list of cid.

var template = new HtmlEmailTemplate();
template.Load("<head><title>{{@begin section title}}Hello {{# Name }}{{@end section}}!</title></head>" +
"<body>{{#html "Here's an image"}} <img src=\"{{cid sample.png}}\" /></body>");
template.AddArgument("Name", typeof(string));

string result = template.Run("Meziantou", out var metadata);

Assert.AreEqual("<head><title>Hello Meziantou!</title></head><body>Here's an image <img src=\"cid:sample.png\"/></body>", result);
Assert.AreEqual("Hello Meziantou", metadata.Title);
Assert.AreEqual("sample.png", metadata.ContentIdentifiers[0]);
You can’t perform that action at this time.