Learn how to implement license protection in C# with Quick License Manager. Production-ready code examples for validation, hardware locking, trials, and subscriptions.
Software piracy costs the industry billions annually. If you're developing desktop applications in C#, protecting your intellectual property should be a top priority. This guide demonstrates how to implement robust license protection using Quick License Manager (QLM), with practical, production-ready code examples.
The Problem: Why Desktop Apps Are Vulnerable
Desktop applications face unique challenges:
- Direct executable access - Users have the application files on their machine
- Easy to reverse engineer - Without protection, code can be decompiled
- No built-in validation - Desktop apps don't inherently check licenses server-side
- Simple distribution - A single unlicensed copy can be shared infinitely
Without proper licensing controls, you're leaving money on the table while unauthorized users benefit from your hard work.
The Solution: Quick License Manager
This guide demonstrates license protection implementation using Quick License Manager (QLM), a comprehensive licensing solution that's been protecting software for over two decades. QLM provides a proven, production-ready implementation that thousands of developers rely on.
QLM offers key capabilities essential for robust license protection:
- Flexible licensing models - Perpetual, subscription, trial, and floating licenses
- Hardware locking - Bind licenses to specific machines
- Online and offline activation - Works with or without internet connectivity
- E-commerce integration - Seamless integration with major platforms
- Cross-platform support - Windows, macOS, Linux
Implementation Guide
Let's walk through implementing QLM in a C# desktop application.
Prerequisites
Before starting, ensure you have:
- Visual Studio 2019 or later
- .NET Framework 4.6.2+ or .NET Core 3.1+
- Quick License Manager installed (free trial available at https://soraco.co)
Step 1: Set Up Your Product in QLM
First, define your product in the QLM Management Console:
- Open QLM Management Console
- Go to "Define Products" tab
- Click "New"
- Enter your Product Name, Major and Minor version
- Note the automatically generated Product ID and GUID
Step 2: Generate the Integration Code
QLM provides a wizard that generates the necessary code:
- Go to the "Protect Your Application" tab
- Follow the wizard instructions
- The wizard generates a
LicenseValidatorclass customized for your product - It also creates a settings XML file with your product configuration
Step 3: Add License Validation to Your Application
Here's the recommended approach using QLM's official pattern:
using System;
using System.Windows.Forms;
using QlmLicenseLib;
namespace MyProtectedApp
{
static class Program
{
private static LicenseValidator lv;
private static string settingsFile;
private static string wizardExec;
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
System.Reflection.Assembly thisAssembly = System.Reflection.Assembly.GetExecutingAssembly();
string location = System.IO.Path.GetDirectoryName(thisAssembly.Location);
settingsFile = System.IO.Path.Combine(location, "YourProduct.lw.xml");
wizardExec = System.IO.Path.Combine(location, "QlmLicenseWizard.exe");
ValidateLicense();
Application.Run(new MainForm());
}
static void ValidateLicense()
{
lv = new LicenseValidator(settingsFile);
bool needsActivation = false;
string errorMsg = string.Empty;
ELicenseBinding licenseBinding = ELicenseBinding.ComputerName;
if (lv.ValidateLicenseAtStartup(licenseBinding, ref needsActivation, ref errorMsg) == false)
{
int exitCode = DisplayLicenseForm();
if (exitCode == 4)
{
Environment.Exit(0);
}
if (lv.ValidateLicenseAtStartup(licenseBinding, ref needsActivation, ref errorMsg) == false)
{
MessageBox.Show("Unable to validate license. Application will now exit.",
"License Error",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
Environment.Exit(0);
}
}
}
static private int DisplayLicenseForm()
{
string errorMessage;
if (lv.QlmLicenseObject.ValidateSettingsFile(settingsFile, out errorMessage) == false)
{
MessageBox.Show(errorMessage, "Configuration Error",
MessageBoxButtons.OK, MessageBoxIcon.Error);
return 0;
}
string args = String.Format("/settings \"{0}\"", settingsFile);
if (!System.IO.File.Exists(wizardExec))
{
wizardExec = @"C:\Program Files\Soraco\QuickLicenseMgr\QlmLicenseWizard.exe";
}
return lv.QlmLicenseObject.LaunchProcess(wizardExec, args, true, true);
}
}
}
Understanding License Binding
QLM supports multiple binding options:
// Computer Name binding (simplest)
ELicenseBinding licenseBinding = ELicenseBinding.ComputerName;
// Hardware binding (more secure)
ELicenseBinding licenseBinding = ELicenseBinding.ComputerID;
// User-based binding
ELicenseBinding licenseBinding = ELicenseBinding.UserDefined;
Advanced Scenarios
Hardware-Locked Licensing
For strict machine binding:
public bool ActivateLicenseWithHardwareLock(string activationKey)
{
string computerID = lv.QlmLicenseObject.GetComputerID();
string computerName = Environment.MachineName;
string response = string.Empty;
bool activated = lv.QlmLicenseObject.ActivateLicense(
webServiceUrl: lv.QlmLicenseObject.DefaultWebServiceUrl,
activationKey: activationKey,
computerID: computerID,
computerName: computerName,
version: lv.QlmLicenseObject.Version,
userData: string.Empty,
response: out response
);
if (activated)
{
lv.QlmLicenseObject.StoreKeys(activationKey, response);
return true;
}
return false;
}
Trial Period Implementation
QLM automatically tracks trial periods:
public bool IsTrialValid()
{
bool needsActivation = false;
string errorMsg = string.Empty;
bool isValid = lv.ValidateLicenseAtStartup(
ELicenseBinding.ComputerName,
ref needsActivation,
ref errorMsg
);
if (lv.QlmLicenseObject.DaysLeft > 0)
{
Console.WriteLine($"Trial days remaining: {lv.QlmLicenseObject.DaysLeft}");
return true;
}
return isValid;
}
Subscription Management
For subscription-based applications:
public bool ValidateSubscription()
{
bool needsActivation = false;
string errorMsg = string.Empty;
bool isValid = lv.ValidateLicenseAtStartup(
ELicenseBinding.ComputerName,
ref needsActivation,
ref errorMsg
);
if (isValid)
{
DateTime expiryDate = lv.QlmLicenseObject.ExpiryDate;
int daysUntilExpiry = (expiryDate - DateTime.Now).Days;
if (daysUntilExpiry <= 0)
{
MessageBox.Show("Your subscription has expired. Please renew.",
"Subscription Expired",
MessageBoxButtons.OK,
MessageBoxIcon.Warning);
return false;
}
if (daysUntilExpiry <= 7)
{
MessageBox.Show($"Your subscription expires in {daysUntilExpiry} days.",
"Renewal Reminder",
MessageBoxButtons.OK,
MessageBoxIcon.Information);
}
return true;
}
return false;
}
Offline Activation
For environments without internet:
public bool ValidateOfflineLicense(string activationKey)
{
bool isValid = lv.QlmLicenseObject.ValidateLicenseOffline(activationKey);
return isValid;
}
E-commerce Integration
QLM integrates with major platforms including FastSpring, Shopify, WooCommerce, PayPal, and Stripe.
When integrated, QLM automatically:
- Generates unique license keys upon purchase
- Sends activation emails to customers
- Manages license lifecycle
- Handles renewals and upgrades
Best Practices
Secure License Storage
Use encrypted storage:
private void StoreLicenseSecurely(string activationKey, string computerKey)
{
lv.QlmLicenseObject.StoreKeys(activationKey, computerKey);
}
Graceful Network Failure Handling
try
{
bool isValid = lv.ValidateLicenseAtStartup(
ELicenseBinding.ComputerName,
ref needsActivation,
ref errorMsg
);
}
catch (Exception ex)
{
Logger.Log($"License validation error: {ex.Message}");
bool offlineValid = lv.QlmLicenseObject.ValidateLicenseOffline(lv.ActivationKey);
}
User Experience
- Show clear messages when licenses need attention
- Display remaining trial/subscription days proactively
- Make activation as simple as possible
Common Pitfalls
Don't Store Keys in Plain Text
// ❌ WRONG
string key = "ABC123-DEF456";
// ✅ CORRECT
lv.QlmLicenseObject.StoreKeys(activationKey, computerKey);
Don't Ignore Validation Errors
// ❌ WRONG
if (!ValidateLicense()) { }
// ✅ CORRECT
if (!ValidateLicense())
{
ShowActivationDialog();
if (!ValidateLicense())
Application.Exit();
}
Performance
- Startup validation: 200-500ms with network check
- Offline validation: Instant
- Online validation: 1-3 seconds typical
Deployment Checklist
- Settings XML file included
- QlmLicenseLib.dll included
- IsLicense50.dll (x86 and x64) included
- QlmLicenseWizard.exe included
- License Server URL configured
- Product ID and GUID match configuration
- Test activation in clean environment
- Test offline activation
- Test trial expiry
Conclusion
Implementing license protection with Quick License Manager provides enterprise-grade security with minimal complexity. The patterns shown here are production-tested and used by thousands of developers.
Key takeaways:
- Use QLM wizard to generate integration code
- Follow official validation patterns
- Implement proper error handling
- Test thoroughly before deployment
- Balance security with user experience
Resources
- Quick License Manager: https://soraco.co
- Documentation: https://docs.soraco.co
- Downloads: https://soraco.co/quick-license-manager/qlm-downloads/
Have questions? Drop them in the comments! 👇
Top comments (0)