Ecng.Licensing
1.0.54
dotnet add package Ecng.Licensing --version 1.0.54
NuGet\Install-Package Ecng.Licensing -Version 1.0.54
<PackageReference Include="Ecng.Licensing" Version="1.0.54" />
<PackageVersion Include="Ecng.Licensing" Version="1.0.54" />
<PackageReference Include="Ecng.Licensing" />
paket add Ecng.Licensing --version 1.0.54
#r "nuget: Ecng.Licensing, 1.0.54"
#:package Ecng.Licensing@1.0.54
#addin nuget:?package=Ecng.Licensing&version=1.0.54
#tool nuget:?package=Ecng.Licensing&version=1.0.54
Ecng.Licensing
A lightweight licensing library for .NET applications supporting license validation, expiration management, and multi-platform licensing.
Purpose
Ecng.Licensing provides a simple and flexible licensing system for commercial .NET applications. It handles license parsing, validation, feature management, and expiration policies across multiple platforms (Windows, Linux, macOS).
Key Features
- XML-based license format with digital signatures
- Multi-platform license support (Windows, Linux, macOS)
- Feature-based licensing with granular control
- Hardware ID binding for license protection
- License expiration management with configurable actions
- Account-based licensing
- Support for both file-based and byte-array license loading
Installation
Add a reference to the Ecng.Licensing package in your project.
Core Concepts
License Structure
A license contains:
- License ID: Unique identifier for the license
- Issued To: Email or name of the licensee
- Issued Date: When the license was created
- Features: Platform-specific features with expiration dates
- Signature: Digital signature for validation
License Features
Each feature has:
- Name: Feature identifier (e.g., "Trading", "Analytics")
- Expiration Date: When the feature expires
- Expire Action: What happens when the feature expires (PreventWork or PreventUpgrade)
- Hardware ID: Optional hardware binding
- Account: Optional account identifier
- OneApp ID: Optional single-application binding
Usage Examples
Loading a License from File
using Ecng.Licensing;
using System.IO;
// Load license from file
byte[] licenseData = File.ReadAllBytes("license.lic");
var license = new License("license.lic", licenseData);
Console.WriteLine($"License ID: {license.Id}");
Console.WriteLine($"Issued To: {license.IssuedTo}");
Console.WriteLine($"Issued Date: {license.IssuedDate}");
Loading a License from Byte Array
using Ecng.Licensing;
// Load license from embedded resource or byte array
byte[] licenseBytes = GetLicenseFromResource();
var license = new License(licenseBytes);
Accessing License Features
using Ecng.Licensing;
using System.Runtime.InteropServices;
// Get features for the current platform
var currentPlatform = OSPlatform.Windows; // or OSPlatform.Linux, OSPlatform.OSX
if (license.Features.TryGetValue(currentPlatform, out var features))
{
foreach (var feature in features)
{
Console.WriteLine($"Feature: {feature.Name}");
Console.WriteLine($"Expires: {feature.ExpirationDate}");
Console.WriteLine($"Action on expire: {feature.ExpireAction}");
if (!string.IsNullOrEmpty(feature.HardwareId))
Console.WriteLine($"Hardware ID: {feature.HardwareId}");
if (!string.IsNullOrEmpty(feature.Account))
Console.WriteLine($"Account: {feature.Account}");
}
}
Checking Feature Availability
using Ecng.Licensing;
using System.Linq;
using System.Runtime.InteropServices;
public bool IsFeatureAvailable(License license, string featureName)
{
var currentPlatform = OSPlatform.Windows;
if (!license.Features.TryGetValue(currentPlatform, out var features))
return false;
var feature = features.FirstOrDefault(f => f.Name == featureName);
if (feature == null)
return false;
// Check if feature has expired
if (DateTime.UtcNow > feature.ExpirationDate)
{
if (feature.ExpireAction == LicenseExpireActions.PreventWork)
return false;
}
return true;
}
// Usage
if (IsFeatureAvailable(license, "Trading"))
{
Console.WriteLine("Trading feature is available");
}
Validating Hardware ID
using Ecng.Licensing;
using System.Linq;
using System.Runtime.InteropServices;
public bool ValidateHardwareId(License license, string currentHardwareId)
{
var currentPlatform = OSPlatform.Windows;
if (!license.Features.TryGetValue(currentPlatform, out var features))
return false;
// If any feature has a hardware ID, validate it
var featuresWithHwId = features.Where(f => !string.IsNullOrEmpty(f.HardwareId));
if (!featuresWithHwId.Any())
return true; // No hardware binding
return featuresWithHwId.Any(f => f.HardwareId.Equals(currentHardwareId,
StringComparison.OrdinalIgnoreCase));
}
Checking License Expiration
using Ecng.Licensing;
using System.Linq;
public class LicenseStatus
{
public bool IsValid { get; set; }
public bool IsExpired { get; set; }
public DateTime? ExpirationDate { get; set; }
public LicenseExpireActions? ExpireAction { get; set; }
}
public LicenseStatus GetLicenseStatus(License license, string featureName)
{
var currentPlatform = System.Runtime.InteropServices.OSPlatform.Windows;
var status = new LicenseStatus { IsValid = false };
if (!license.Features.TryGetValue(currentPlatform, out var features))
return status;
var feature = features.FirstOrDefault(f => f.Name == featureName);
if (feature == null)
return status;
status.ExpirationDate = feature.ExpirationDate;
status.ExpireAction = feature.ExpireAction;
status.IsExpired = DateTime.UtcNow > feature.ExpirationDate;
status.IsValid = !status.IsExpired ||
feature.ExpireAction == LicenseExpireActions.PreventUpgrade;
return status;
}
// Usage
var status = GetLicenseStatus(license, "Analytics");
if (status.IsExpired)
{
Console.WriteLine($"License expired on {status.ExpirationDate}");
Console.WriteLine($"Action: {status.ExpireAction}");
}
Working with Multiple Features
using Ecng.Licensing;
using System.Linq;
using System.Runtime.InteropServices;
public class LicenseManager
{
private readonly License _license;
private readonly OSPlatform _platform;
public LicenseManager(License license)
{
_license = license;
_platform = GetCurrentPlatform();
}
private OSPlatform GetCurrentPlatform()
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
return OSPlatform.Windows;
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
return OSPlatform.Linux;
if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
return OSPlatform.OSX;
throw new PlatformNotSupportedException();
}
public bool HasFeature(string featureName)
{
if (!_license.Features.TryGetValue(_platform, out var features))
return false;
return features.Any(f => f.Name.Equals(featureName,
StringComparison.OrdinalIgnoreCase));
}
public IEnumerable<string> GetActiveFeatures()
{
if (!_license.Features.TryGetValue(_platform, out var features))
return Enumerable.Empty<string>();
return features
.Where(f => DateTime.UtcNow <= f.ExpirationDate ||
f.ExpireAction == LicenseExpireActions.PreventUpgrade)
.Select(f => f.Name);
}
public IEnumerable<LicenseFeature> GetExpiringFeatures(int daysAhead)
{
if (!_license.Features.TryGetValue(_platform, out var features))
return Enumerable.Empty<LicenseFeature>();
var threshold = DateTime.UtcNow.AddDays(daysAhead);
return features.Where(f =>
f.ExpirationDate > DateTime.UtcNow &&
f.ExpirationDate <= threshold);
}
}
// Usage
var manager = new LicenseManager(license);
// Check if feature exists
if (manager.HasFeature("Trading"))
{
Console.WriteLine("Trading feature is licensed");
}
// Get all active features
foreach (var feature in manager.GetActiveFeatures())
{
Console.WriteLine($"Active feature: {feature}");
}
// Get features expiring in next 30 days
foreach (var feature in manager.GetExpiringFeatures(30))
{
Console.WriteLine($"Feature {feature.Name} expires on {feature.ExpirationDate}");
}
Accessing License Properties
using Ecng.Licensing;
// Access basic license information
Console.WriteLine($"License Version: {license.Version}");
Console.WriteLine($"License ID: {license.Id}");
Console.WriteLine($"Issued To: {license.IssuedTo}");
Console.WriteLine($"Issued Date: {license.IssuedDate:yyyy-MM-dd}");
// Access raw license data
byte[] originalBody = license.Body;
byte[] bodyWithoutSignature = license.BodyWithoutSignature;
byte[] signature = license.Signature;
// Get string representation
string licenseInfo = license.ToString(); // Returns "N{Id} ({HardwareId})"
License Expire Actions
The LicenseExpireActions enum defines what happens when a license expires:
- PreventWork: The feature becomes completely unavailable after expiration
- PreventUpgrade: The feature continues to work but cannot be upgraded to newer versions
using Ecng.Licensing;
public void HandleExpiration(LicenseFeature feature)
{
switch (feature.ExpireAction)
{
case LicenseExpireActions.PreventWork:
Console.WriteLine("Feature will stop working after expiration");
// Disable feature completely
break;
case LicenseExpireActions.PreventUpgrade:
Console.WriteLine("Feature will continue working but no updates allowed");
// Allow current version usage only
break;
}
}
Best Practices
- Validate Licenses Early: Check license validity during application startup
- Handle Expiration Gracefully: Show warnings before license expiration
- Secure License Storage: Store license files securely and validate signatures
- Hardware Binding: Use hardware IDs for additional security when needed
- Multi-Platform Support: Check platform-specific features appropriately
- Regular Validation: Periodically re-validate licenses during application runtime
Platform Support
- .NET Standard 2.0+
- .NET 6.0+
- .NET 10.0+
Supports Windows, Linux, and macOS platforms.
Dependencies
- Ecng.Common
- Ecng.Collections
- Ecng.Localization
License Format
Licenses are stored in XML format with the following structure:
<license>
<ver>1.0</ver>
<id>12345</id>
<issuedTo>user@example.com</issuedTo>
<issuedDate>20240101 00:00:00</issuedDate>
<platforms>
<platform name="Windows">
<feature name="Trading" expire="20251231 23:59:59" expireAction="PreventWork" hardwareId="" account="" />
<feature name="Analytics" expire="20251231 23:59:59" expireAction="PreventUpgrade" hardwareId="" account="" />
</platform>
</platforms>
<signature>BASE64_SIGNATURE</signature>
</license>
See Also
- Ecng.Common - Common utilities and extensions
- Ecng.Collections - Collection utilities
- Ecng.Localization - Localization support
| Product | Versions 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 was computed. 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 was computed. 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. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.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 was computed. |
| .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. |
-
.NETStandard 2.0
- Ecng.Collections (>= 1.0.277)
- Ecng.Localization (>= 1.0.238)
-
net10.0
- Ecng.Collections (>= 1.0.277)
- Ecng.Localization (>= 1.0.238)
-
net6.0
- Ecng.Collections (>= 1.0.277)
- Ecng.Localization (>= 1.0.238)
NuGet packages (2)
Showing the top 2 NuGet packages that depend on Ecng.Licensing:
| Package | Downloads |
|---|---|
|
StockSharp.Licensing
Licensing components. More info on web site https://stocksharp.com/store/ |
|
|
StockSharp.Web.DomainModel
StockSharp WebApi |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.54 | 0 | 1/14/2026 |
| 1.0.53 | 36 | 1/13/2026 |
| 1.0.52 | 48 | 1/13/2026 |
| 1.0.51 | 65 | 1/9/2026 |
| 1.0.50 | 61 | 1/9/2026 |
| 1.0.49 | 85 | 1/4/2026 |
| 1.0.48 | 89 | 12/30/2025 |
| 1.0.47 | 89 | 12/29/2025 |
| 1.0.46 | 89 | 12/26/2025 |
| 1.0.45 | 87 | 12/26/2025 |
| 1.0.44 | 88 | 12/26/2025 |
| 1.0.43 | 99 | 12/26/2025 |
| 1.0.42 | 175 | 12/25/2025 |
| 1.0.41 | 176 | 12/25/2025 |
| 1.0.40 | 170 | 12/22/2025 |
| 1.0.39 | 155 | 12/21/2025 |
| 1.0.38 | 197 | 12/19/2025 |
| 1.0.37 | 234 | 12/19/2025 |
| 1.0.36 | 264 | 12/17/2025 |
| 1.0.35 | 247 | 12/15/2025 |
| 1.0.34 | 246 | 12/15/2025 |
| 1.0.33 | 205 | 12/14/2025 |
| 1.0.32 | 120 | 12/12/2025 |
| 1.0.31 | 120 | 12/12/2025 |
| 1.0.30 | 118 | 12/12/2025 |
| 1.0.29 | 120 | 12/12/2025 |
| 1.0.28 | 124 | 12/12/2025 |
| 1.0.27 | 676 | 12/2/2025 |
| 1.0.26 | 676 | 12/2/2025 |
| 1.0.25 | 679 | 12/2/2025 |
| 1.0.24 | 259 | 11/30/2025 |
| 1.0.23 | 125 | 11/29/2025 |
| 1.0.22 | 134 | 11/28/2025 |
| 1.0.21 | 141 | 11/28/2025 |
| 1.0.20 | 187 | 11/27/2025 |
| 1.0.19 | 183 | 11/24/2025 |
| 1.0.18 | 192 | 11/24/2025 |
| 1.0.17 | 188 | 11/23/2025 |
| 1.0.16 | 207 | 11/22/2025 |
| 1.0.15 | 408 | 11/20/2025 |
| 1.0.14 | 417 | 11/18/2025 |
| 1.0.13 | 401 | 11/18/2025 |
| 1.0.12 | 291 | 11/13/2025 |
| 1.0.11 | 247 | 11/10/2025 |
| 1.0.10 | 144 | 11/1/2025 |
| 1.0.9 | 194 | 10/28/2025 |
| 1.0.8 | 193 | 10/27/2025 |
| 1.0.7 | 185 | 10/27/2025 |
| 1.0.6 | 119 | 10/25/2025 |
| 1.0.5 | 137 | 10/3/2025 |
| 1.0.4 | 197 | 9/28/2025 |
| 1.0.3 | 201 | 9/25/2025 |
| 1.0.2 | 3,409 | 9/5/2025 |
| 1.0.1 | 3,879 | 8/30/2025 |
| 1.0.0 | 360 | 8/20/2025 |