Walter.IO 2024.3.26.1111

The ID prefix of this package has been reserved for one of the owners of this package by NuGet.org. Prefix Reserved
dotnet add package Walter.IO --version 2024.3.26.1111
NuGet\Install-Package Walter.IO -Version 2024.3.26.1111
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Walter.IO" Version="2024.3.26.1111" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Walter.IO --version 2024.3.26.1111
#r "nuget: Walter.IO, 2024.3.26.1111"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install Walter.IO as a Cake Addin
#addin nuget:?package=Walter.IO&version=2024.3.26.1111

// Install Walter.IO as a Cake Tool
#tool nuget:?package=Walter.IO&version=2024.3.26.1111

WALTER

Introducing the WALTER Framework: Workable Algorithms for Location-aware Transmission, Encryption Response. Designed for modern developers, WALTER is a groundbreaking suite of NuGet packages crafted for excellence in .NET Standard 2.0, 2.1, Core 3.1, and .NET 6, 7, 8, as well as C++ environments. Emphasizing 100% AoT support and reflection-free operations, this framework is the epitome of performance and stability.

Whether you're tackling networking, encryption, or secure communication, WALTER offers unparalleled efficiency and precision in processing, making it an essential tool for developers who prioritize speed and memory management in their applications.

About the Walter.IO Package

Basically there a 2 main interfaces in the Nuget package

  • IDiskGuard
  • FileInfo extensions

IDiskGuard

The IDiskGuard monitors and alerts if there are any uncontrolled disk activities where data is altered.

Features

  • Real-Time Disk Activity Monitoring: IDiskGuard actively watches specified directories for changes, including file creations, modifications, and deletions.
  • Event-Driven Alerts: Triggers events when unauthorized disk manipulations are detected, allowing for immediate response.
  • Flexible Monitoring: Supports monitoring specific directories with customizable file filters and the option to include subdirectories.
  • Easy Integration: While demonstrated with IDiskGuard is designed for broad applicability across various types of applications.

Getting Started

The bellow sample show you one of many ways that you can integrate and configure IDiskGuard.


using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;
using System.IO;
using Walter.BOM;
using Walter.IO;

namespace YourNamespace
{
    public static class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureServices((hostContext, services) =>
                {
                    services.AddHostedService<DiskMonitorService>();
                    services.AddSecureDiskMonitor();
                });
    }

    public class DiskMonitorService : BackgroundService
    {
        private readonly IDiskGuard _diskGuard;

        public DiskMonitorService(IDiskGuard diskGuard)
        {
            _diskGuard = diskGuard;
        }

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            var monitoredDirectory = @"path\to\monitored\directory";

            // Start monitoring the directory
            _diskGuard.StartMonitoring(new DirectoryInfo(monitoredDirectory), "*.*", true);
            _diskGuard.OnDiskManipulation += DiskGuard_OnDiskManipulation;

            stoppingToken.Register(() => 
            {
                // Cleanup code when the service is stopping
                _diskGuard.StopMonitoring(new DirectoryInfo(monitoredDirectory), "*.*");
            });

            while (!stoppingToken.IsCancellationRequested)
            {
                // The service will keep running, monitoring disk activities.
                // Implement any additional periodic checks or maintenance tasks here.

                await Task.Delay(TimeSpan.FromMinutes(1), stoppingToken);
            }
        }

        private void DiskGuard_OnDiskManipulation(object sender, DiskManipulationEventArgs e)
        {
            // Example padding check for manipulated files
            var fileInfo = new FileInfo(e.Violation.Path);
            if (fileInfo.Exists && fileInfo.CountPaddingBytesChunked() > 0)
            {
                // Handle detection of significant padding in the manipulated file
                Console.WriteLine($"Unauthorized manipulation with padding detected on file: {e.Violation.Path}");
            }
            // Implement additional handling logic for detected disk manipulations
        }
    }
}

Key Components:

  • Program: Sets up the host builder and configures services, registering DiskMonitorService as a hosted service and adding IDiskGuard to the DI container.
  • DiskMonitorService: A background service that starts disk monitoring on application start and keeps running until the application shuts down. It listens for IDiskGuard's OnDiskManipulation event to detect and respond to unauthorized disk manipulations, including checking for significant padding in altered files.

Steps to Use

  • Replace "path\to\monitored\directory" with the actual path of the directory you want to monitor.
  • Implement any additional logic you require in the DiskGuard_OnDiskManipulation method, especially for handling detected unauthorized disk manipulations and padding analysis.

This setup allows IDiskGuard to continuously monitor specified directories in the background, making it an efficient solution for detecting and responding to potential security threats or unauthorized changes in real-time, without requiring direct interaction with user-facing components like controllers.

FileInfo Extension Methods Overview

The Walter.IO package enriches your application with powerful FileInfo extension methods, designed to enhance file analysis and security measures. Among these, two standout methods provide essential capabilities for detecting potential security threats and ensuring data integrity:

CountPaddingBytesChunked()

This method efficiently calculates the number of padding bytes present at the end of a file. By leveraging chunked reading strategies, it optimizes performance and minimizes memory usage, making it exceptionally well-suited for processing large files. This capability is crucial for analyzing file structures and detecting anomalies that could signify data corruption or tampering.

Key Benefits:
  • Performance-Optimized: Tailored for large files with minimal performance impact.
  • Security Analysis: Aids in the identification of file tampering or corruption.

ContainsMoreThanOrEqualTo(percentage)

Evaluates whether the padding within a file constitutes a specified percentage (or more) of the file's total size. This method is instrumental in uncovering files that may have been deliberately modified to circumvent malware detection mechanisms through the introduction of excessive padding. Such modifications can alter a file's hash signature, enabling it to evade traditional detection techniques based on known signatures.

Key Benefits:
  • Malware Detection: Helps identify files potentially altered to bypass hash-based malware detection.
  • Customizable Threshold: Allows specification of the padding percentage threshold for targeted analysis.

Practical Applications

Detecting excessive padding in files is more than just a matter of maintaining data integrity. It's a critical security practice. Malicious actors often manipulate file padding to change hash signatures, thereby evading detection by antivirus programs and intrusion detection systems. By employing the ContainsMoreThanOrEqualTo method, developers and security professionals can pinpoint files with unusual padding patterns, flagging them for further investigation or automated responses.

Example Usage:

Detecting a file with excessive padding could be as straightforward as:

FileInfo suspiciousFile = new FileInfo("path/to/suspect/file.exe");

// Check if the file has padding exceeding 30% of its total size
bool isAltered = suspiciousFile.ContainsMoreThanOrEqualTo(30);

if (isAltered)
{
    Console.WriteLine($"File: {suspiciousFile.Name} may have been altered to evade malware detection.");
}

By integrating these FileInfo extensions into your security protocols, you can enhance your application's resilience against sophisticated cyber threats and ensure a higher level of data integrity and reliability.

Comparing File Padding Changes Between Scans

This example demonstrates how to monitor files for changes in padding, which could indicate tampering or unauthorized alterations aimed at evading detection.

using System;
using System.Collections.Generic;
using System.IO;
using Walter.IO;

public class PaddingMonitor
{
    private Dictionary<string, long> _lastScanResults = new Dictionary<string, long>();

    public void ScanDirectoryForPaddingChanges(string directoryPath)
    {
        DirectoryInfo directory = new DirectoryInfo(directoryPath);
        FileInfo[] files = directory.GetFiles("*.*", SearchOption.AllDirectories);

        foreach (var file in files)
        {
            long currentPadding = file.CountPaddingBytesChunked();
            if (_lastScanResults.TryGetValue(file.FullName, out long lastPadding))
            {
                if (currentPadding != lastPadding)
                {
                    Console.WriteLine($"Padding change detected in {file.Name}. Previous: {lastPadding}, Current: {currentPadding}");
                }
            }
            else
            {
                Console.WriteLine($"New file detected: {file.Name} with {currentPadding} padding bytes.");
            }

            // Update the last scan results
            _lastScanResults[file.FullName] = currentPadding;
        }
    }
}

Instantiate PaddingMonitor and call ScanDirectoryForPaddingChanges periodically or upon specific triggers to check for padding changes in the monitored directory.

File Comparison Extension: FileIsEqualToIgnoringPadding

The FileIsEqualToIgnoringPadding extension method is an invaluable tool in the Walter.IO package designed to enhance file integrity checks by comparing the binary content of two files, ignoring any trailing padding. This method is particularly useful for identifying files that have been altered to evade hash-based detection mechanisms by adding or modifying padding.

Use Case

In cybersecurity, verifying the integrity of files is crucial, especially for system-critical executables like powershell.exe. Malicious actors might duplicate and slightly alter such executables (e.g., by adding padding) to bypass security checks. The FileIsEqualToIgnoringPadding method enables developers to detect such tampering by comparing the core content of files, excluding padding variations.

Example: Comparing PowerShell Executable

This example demonstrates how to use FileIsEqualToIgnoringPadding to compare a downloaded file with the system's powershell.exe, focusing on their content while ignoring padding differences.

using System;
using System.IO;
using Walter.IO;

class Program
{
    static void Main(string[] args)
    {
    
        FileInfo originalPowerShell = new FileInfo(@"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe");
        FileInfo downloadedFile = new FileInfo(@"path\to\downloaded\file.exe"); // Update with the actual file path

        // Compare the original PowerShell executable with a downloaded file, ignoring padding
        bool areFilesEqual = originalPowerShell.FileIsEqualToIgnoringPadding(downloadedFile);

        if (areFilesEqual)
        {
            Console.WriteLine("The downloaded file is identical to powershell.exe, ignoring padding.");
        }
        else
        {
            Console.WriteLine("The downloaded file differs from powershell.exe or does not exist.");
        }
    }
}


### Yuu can use this method to see if malware is using hash signature changes in order to evaid malware detection signatures

```c#
using Walter.IO;

public static partial class Program
{
    public static void Main(string[] args)
    {
        // Define the path to the folder you want to scan. Here, using the Downloads folder as an example.
        string folderPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Downloads");

        // Ensure the folder exists
        if (!Directory.Exists(folderPath))
        {
            Console.WriteLine("The specified folder does not exist.");
            return;
        }
        // Create a "poison" file with a specific amount of padding
        var poisonFilePath = Path.Combine(folderPath, $"sample_{DateTime.Now:yy-MM-dd-HH-mm-ss-fff}.bin");
        long totalFileSizeInBytes = 1024 * 1024; // 1 MB total size
        int paddingPercentage = 20; // Target 20% of the file size as padding
        FileWithPaddingCreator.CreateFileWithPadding(poisonFilePath, totalFileSizeInBytes, paddingPercentage);

        // Get all files in the folder
        FileInfo[] files = new DirectoryInfo(folderPath).GetFiles();

        
        

        Console.WriteLine("Scanning files for significant padding...");

        // Use Parallel.ForEach for efficient multi-threaded processing
        Parallel.ForEach(files, (file) =>
        {
            long fileSize = file.Length;
            if (fileSize == 0) return; // Skip empty files

            // Calculate the padding threshold based on the file size (e.g., 20% of the file size)


            // Use the extension method to count padding bytes
            long paddingBytesCount = file.CountPaddingBytesChunked();
            var padding = file.CountPaddingBytes();


            if (padding > 0)
            {
                decimal percentagePadding = (decimal)padding / file.Length * 100; // Correct percentage calculation
                if (paddingBytesCount > 0)
                {
                    Console.WriteLine($"Padding {file.Name} ({file.Age()} age): {padding:N0} bytes of padding ({percentagePadding:N2}%)");
                }
            }

        });
        if(File.Exists(poisonFilePath)) 
        {
            File.Delete(poisonFilePath);
        }
        Console.WriteLine("Scanning complete.");

#if !DEBUG
        Console.WriteLine("Press any to to exit..");
        Console.ReadKey();
#endif
    }
}
Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 is compatible.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 is compatible. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (2)

Showing the top 2 NuGet packages that depend on Walter.IO:

Package Downloads
Walter.DataTools.MsSql The ID prefix of this package has been reserved for one of the owners of this package by NuGet.org.

Package used by Firewall products for interacting with sql server and is used to create and apply updates to database DDL objects This package will be re-factored in the future separating base classes into a new package and have the MSSQL and MySql in their own packages.

Walter.Web.FireWall The ID prefix of this package has been reserved for one of the owners of this package by NuGet.org.

The application firewall that can be used in .NET 5.0, .Net CORE 3.1 and .NET standard 2.1 applications that would benefit for protection against several types of attacks and is easily activated by service integration. services.AddFireWall(FireWallTrial.License, FireWallTrial.DomainKey , domainName: new Uri("https://www.your-domain.com", UriKind.Absolute) , options => { //your options }); Have a look at the GitHub samples at https://github.com/ASP-WAF/FireWall and https://github.com/ASP-WAF/FireWall/wiki to see how to use the firewall in applications. You can view the firewall in action using https://www.asp-waf.com/Firewall You can get started with the firewall using the samples shown in https://www.asp-waf.com/download/ASP-WAF-FireWall-Getting-Started.pdf as well as the on line documentation at https://firewallapi.asp-waf.com/

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
2024.3.26.1111 54 3/26/2024
2024.3.19.2310 78 3/19/2024
2024.3.12.1022 83 3/12/2024
2024.3.7.1756 87 3/7/2024
2023.11.13.1117 1,240 11/13/2023
2023.10.26.1502 1,136 10/29/2023
2023.10.12.1926 1,246 10/12/2023
2023.9.14.812 1,344 9/14/2023
2023.9.7.1748 1,375 9/7/2023
2023.9.7.1241 1,342 9/7/2023
2023.9.6.1001 1,317 9/6/2023
2023.9.5.1246 1,351 9/5/2023
2023.9.5.1032 1,323 9/5/2023
2023.8.31.1522 1,385 8/31/2023
2023.8.29.1040 1,375 8/29/2023
2023.8.17.901 1,443 8/17/2023
2023.8.9.1314 1,551 8/9/2023
2023.8.2.750 1,604 8/2/2023
2023.7.12.830 1,576 7/12/2023
2023.7.5.1419 1,685 7/6/2023
2023.6.14.1628 1,720 6/14/2023
2023.6.11.1304 1,840 6/11/2023
2023.5.30.1640 1,799 5/30/2023
2023.5.4.1552 1,909 5/4/2023
2023.5.1.1524 1,874 5/1/2023
2023.4.29.910 2,068 4/29/2023
2023.4.12.1236 2,076 4/12/2023
2023.3.22.1456 2,258 3/22/2023
2023.3.14.1356 2,343 3/14/2023
2023.3.1.810 2,356 3/1/2023
2023.2.25.11857 2,386 2/25/2023
2023.2.22.27 2,384 2/22/2023
2023.2.15.1413 2,469 2/15/2023
2023.2.11.1628 2,538 2/11/2023
2023.1.11.534 2,714 1/11/2023
2022.12.30.711 2,790 12/30/2022
2022.12.16.1536 996 12/16/2022
2022.12.15.1241 968 12/16/2022
2022.12.15.1108 2,963 12/15/2022
2022.12.14.648 2,951 12/14/2022
2022.11.27.1059 2,936 11/27/2022
2022.11.21.338 3,028 11/21/2022
2022.11.14.1819 3,136 11/14/2022
2022.11.13.917 3,130 11/13/2022
2022.11.7.1632 977 11/13/2022
2022.10.31.740 6,080 11/1/2022
2022.10.15.652 6,750 10/15/2022
2022.10.1.810 7,115 10/1/2022
2022.9.26.1444 7,250 9/26/2022
2022.9.14.1508 7,267 9/14/2022
2022.9.14.809 7,327 9/14/2022
2022.9.8.1009 7,496 9/8/2022
2022.8.20.1007 7,425 8/20/2022
2022.8.1.1 7,539 7/31/2022
2022.7.1300 7,674 7/1/2022
2022.7.31.1016 7,589 7/31/2022
2022.7.15.841 7,609 7/15/2022
2022.6.21.647 7,641 6/21/2022
2022.5.18.638 7,660 5/19/2022
2022.5.16.853 7,720 5/19/2022
2022.5.16.816 7,658 5/16/2022
2022.5.4.1010 7,603 5/4/2022
2022.4.10.947 8,188 4/10/2022
2022.4.10.925 8,163 4/10/2022
2022.4.10.828 8,103 4/10/2022
2022.4.1.1545 8,215 4/1/2022
2022.3.31.823 7,326 3/31/2022
2022.3.26.1103 8,352 3/26/2022
2022.3.26.820 8,056 3/26/2022
2022.3.25.840 7,431 3/26/2022
2022.3.24.1701 2,097 3/25/2022
2022.2.16.1131 8,457 2/17/2022
2022.2.16.834 8,335 2/17/2022
2022.2.15.824 2,982 2/17/2022
2022.2.11.1452 3,746 2/17/2022
2022.2.11.931 1,635 2/17/2022
2022.2.5.1114 8,685 2/5/2022
2022.1.17.1158 8,379 1/17/2022
2022.1.10.1505 8,578 1/10/2022
2022.1.10.537 7,977 1/10/2022
2022.1.5.1139 7,590 1/8/2022
2021.12.28.1452 8,570 12/28/2021
2021.12.16.812 8,295 12/16/2021
2021.11.23.1528 14,417 11/24/2021
2021.11.21.925 13,731 11/22/2021
2021.11.19.1503 1,367 11/22/2021
2021.11.19.847 9,164 11/19/2021
2021.11.18.1824 8,814 11/16/2021
2021.11.10.852 9,308 11/10/2021
2021.11.9.2021 9,017 11/9/2021
2021.11.8.2109 6,961 11/9/2021
2021.11.8.1612 7,495 11/8/2021
2021.11.7.1021 7,670 11/8/2021
2021.11.3.1612 7,700 11/4/2021
2021.11.1.1102 6,457 11/1/2021
2021.10.25.1206 7,902 10/25/2021
2021.10.23.1310 7,790 10/25/2021
2021.10.19.1522 7,855 10/19/2021
2021.10.16.1325 7,749 10/18/2021
2021.10.6.1546 7,843 10/6/2021
2021.10.5.1450 7,938 10/5/2021
2021.10.4.1155 7,991 10/5/2021
2021.10.4.807 1,635 10/5/2021
2021.10.1.753 8,022 10/1/2021
2021.9.27.1005 7,380 9/28/2021
2021.9.26.1913 8,124 9/26/2021
2021.9.19.1015 7,923 9/19/2021
2021.9.17.1702 4,947 9/17/2021
2021.9.17.1449 10,368 9/17/2021
2021.9.13.1600 6,082 9/13/2021
2021.9.12.1100 4,694 9/13/2021
2021.9.11.2004 7,378 9/11/2021
2021.9.9.1110 7,772 9/9/2021
2021.9.7.1901 7,910 9/8/2021
2021.9.7.1121 8,009 9/7/2021
2021.9.7.927 1,627 9/7/2021
2021.9.6.1518 7,572 9/7/2021
2021.9.4.1124 7,925 9/4/2021
2021.9.2.708 7,599 9/4/2021
2021.9.0.1259 7,600 9/2/2021
2021.8.21.1230 21,124 8/22/2021
2021.8.18.1500 8,012 8/18/2021
2021.8.18.930 7,940 8/18/2021
2021.8.14.1600 7,919 8/16/2021
2021.8.14.829 4,095 8/14/2021
2021.8.9.1105 7,945 8/9/2021
2021.8.8.1612 7,659 8/8/2021
2021.8.8.1138 7,045 8/8/2021
2021.8.6.1044 7,748 8/6/2021
2021.8.4.1355 8,263 8/5/2021
2021.7.30.2118 8,210 7/31/2021
2021.7.27.926 8,199 7/28/2021
2021.7.23.931 8,249 7/26/2021
2021.7.22.1456 7,831 7/23/2021
2021.7.15.1547 7,906 7/15/2021
2021.7.13.812 7,790 7/13/2021
2021.7.8.1527 8,017 7/10/2021
2021.7.5.1649 7,182 7/5/2021
2021.6.29.1453 8,296 6/30/2021
2021.6.26.1753 8,520 6/27/2021
2021.6.25.1849 8,211 6/25/2021
2021.6.24.1518 8,092 6/24/2021
2021.6.20.729 8,807 6/20/2021
2021.6.15.2006 8,214 6/15/2021
2021.6.14.2025 8,594 6/15/2021
2021.6.13.2035 8,864 6/14/2021
2021.6.12.1154 8,267 6/13/2021
2021.6.9.1120 8,509 6/9/2021
2021.6.7.2103 1,643 6/7/2021
2021.6.3.1509 8,217 6/3/2021
2021.5.31.1533 8,488 5/31/2021
2021.5.31.1415 8,479 5/31/2021
2021.5.25.1732 7,473 5/25/2021
2021.5.24.1128 8,216 5/24/2021
2021.5.24.1019 7,952 5/24/2021
2021.5.12.1054 8,117 5/12/2021
2021.5.12.637 6,393 5/12/2021
2021.5.10.1442 7,448 5/11/2021
2021.5.8.1226 7,869 5/8/2021
2021.5.6.2037 6,918 5/6/2021
2021.5.5.1901 8,105 5/6/2021
2021.5.3.1621 8,184 5/4/2021
2021.5.1.905 8,494 5/1/2021
2021.4.28.1511 8,258 4/28/2021
2021.4.20.1520 8,873 4/21/2021
2021.4.16.738 8,726 4/21/2021
2021.4.14.1216 8,523 4/16/2021
2021.4.9.1538 8,379 4/13/2021
2021.4.8.947 8,436 4/13/2021
2021.4.6.1235 8,368 4/6/2021
2021.4.5.1653 8,191 4/5/2021
2021.4.1.913 8,406 4/1/2021
2021.3.31.2003 8,299 4/1/2021
2021.3.18.1622 8,655 3/18/2021
2021.3.3.1259 7,359 3/3/2021
2021.3.2.1415 7,846 3/2/2021
2021.3.1.11 7,395 2/28/2021
2021.3.1.1 7,685 2/27/2021
2021.3.1 7,480 2/27/2021
2021.2.23.6 6,715 2/23/2021
2021.2.21.1 7,833 2/21/2021
2021.2.20.1 7,539 2/20/2021
2021.2.19.2 7,233 2/19/2021
2021.2.18.6 6,238 2/19/2021
2021.2.17.1 7,253 2/17/2021
2021.2.16.1 7,703 2/16/2021
2021.2.15.3 7,647 2/15/2021
2021.2.15.1 7,576 2/14/2021
2021.2.14.3 7,044 2/14/2021
2021.2.12.6 7,399 2/12/2021
2021.2.12.2 7,593 2/12/2021
2021.2.11.1 6,004 2/11/2021
2021.2.10.1 7,039 2/10/2021
2021.2.8.1 7,504 2/9/2021
2021.2.7.1 13,873 2/6/2021
2020.12.27.6 7,779 12/27/2020
2020.12.27.1 7,140 12/27/2020
2020.12.26.7 6,958 12/27/2020
2020.12.26.5 7,668 12/27/2020
2020.12.26.3 7,703 12/27/2020

3  March 2024
- Migrate to .net 8 (including AoT)
- Make trimmable

17 November 2023
- Integrate .Net 8

12 October 2023
- Build using SDK-7.0.402 and SDK-6.0.415
- Update Package references

14 September 2023
- SDK 7.0.401/SDK 6.0.414
- Update to new NuGet Packages

12 July 2023
- Update to SDK SP 6.0.412. and 7.0.306
- Update package references
...

23 December 2020
- Initial release