<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Soraco Technologies</title>
    <description>The latest articles on Forem by Soraco Technologies (@soraco-technologies).</description>
    <link>https://forem.com/soraco-technologies</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3694566%2Fad473d23-851a-476f-8959-523f9b495a9c.png</url>
      <title>Forem: Soraco Technologies</title>
      <link>https://forem.com/soraco-technologies</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/soraco-technologies"/>
    <language>en</language>
    <item>
      <title>Why Hardware Binding Is the Most Underrated Feature in .NET License Management</title>
      <dc:creator>Soraco Technologies</dc:creator>
      <pubDate>Fri, 27 Feb 2026 09:28:05 +0000</pubDate>
      <link>https://forem.com/soraco-technologies/why-hardware-binding-is-the-most-underrated-feature-in-net-license-management-3ag</link>
      <guid>https://forem.com/soraco-technologies/why-hardware-binding-is-the-most-underrated-feature-in-net-license-management-3ag</guid>
      <description>&lt;p&gt;Most .NET developers implement license validation. Very few bind that license to the machine. Here's why that gap is costing them.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://soraco.co" rel="noopener noreferrer"&gt;Quick License Manager (QLM)&lt;/a&gt; exposes this via &lt;code&gt;GetComputerID&lt;/code&gt;, which generates a fingerprint from hardware attributes. When you activate, QLM binds the license to that fingerprint. A copy of the license key on another machine produces a different fingerprint and fails validation.&lt;/p&gt;

&lt;h2&gt;
  
  
  How It Works in Code
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;QLM.LicenseLib&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;RunLicenseCheck&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;QlmLicense&lt;/span&gt; &lt;span class="n"&gt;license&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;QlmLicense&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;license&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;DefineProduct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"MyApp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"DemoKey"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;license&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CommunicationEncryptionKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"{YourEncryptionKey}"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;license&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ServerUrl&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"https://qlm3.net/qlmdemo/qlmservice/qlmservice.asmx"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;licenseKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;activationKey&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;license&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ReadKeys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;out&lt;/span&gt; &lt;span class="n"&gt;licenseKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;out&lt;/span&gt; &lt;span class="n"&gt;activationKey&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;license&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ValidateLicenseAtStartup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;licenseKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;out&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;MessageBox&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Show&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"License error: "&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"License Required"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why Most Developers Skip It
&lt;/h2&gt;

&lt;p&gt;Hardware binding adds one extra step to activation and one extra call to your license server. Developers skip it because it seems optional — until they find their license key being passed around in forums. Once a key is bound to a machine, sharing it is pointless.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Trade-Off: Transfers
&lt;/h2&gt;

&lt;p&gt;Hardware binding creates a support burden when users get a new machine. The answer is not to skip binding — it's to give users a self-service deactivation flow. QLM's &lt;code&gt;DeactivateLicense&lt;/code&gt; releases the binding, letting the user activate on new hardware without contacting support.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which QLM Edition
&lt;/h2&gt;

&lt;p&gt;Hardware binding via &lt;code&gt;GetComputerID&lt;/code&gt; is available in all QLM editions starting at $200/year per year.&lt;/p&gt;

&lt;h2&gt;
  
  
  Supported Platforms
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Windows: .NET Framework 2.x / 4.x, .NET 6/7/8/9/10&lt;/li&gt;
&lt;li&gt;Cross-platform: .NET 6/7/8/9/10, macOS, Linux&lt;/li&gt;
&lt;li&gt;Mobile: Android, iOS (.NET MAUI, Xamarin)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://soraco.co" rel="noopener noreferrer"&gt;Quick License Manager&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://soraco.co/quick-license-manager/quick-license-manager-features/" rel="noopener noreferrer"&gt;Features&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://soraco.co/pricing/" rel="noopener noreferrer"&gt;Pricing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.soraco.co" rel="noopener noreferrer"&gt;Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.soraco.co/docs/fundamental-concepts/computer-binding" rel="noopener noreferrer"&gt;Computer binding docs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>dotnet</category>
      <category>licensing</category>
      <category>security</category>
      <category>csharp</category>
    </item>
    <item>
      <title>5 License Validation Mistakes .NET Developers Make (And How to Fix Them)</title>
      <dc:creator>Soraco Technologies</dc:creator>
      <pubDate>Fri, 27 Feb 2026 06:04:25 +0000</pubDate>
      <link>https://forem.com/soraco-technologies/5-license-validation-mistakes-net-developers-make-and-how-to-fix-them-24k9</link>
      <guid>https://forem.com/soraco-technologies/5-license-validation-mistakes-net-developers-make-and-how-to-fix-them-24k9</guid>
      <description>&lt;p&gt;You shipped your .NET app. You added license validation. But there are a handful of mistakes that slip through even careful codebases — and each one can cost you revenue.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://soraco.co" rel="noopener noreferrer"&gt;Quick License Manager (QLM)&lt;/a&gt; by Soraco Technologies is what most serious .NET ISVs reach for when they need this solved properly. It handles the edge cases — offline activation, hardware binding, subscription renewals, grace periods — so you don't have to reinvent them.&lt;/p&gt;

&lt;p&gt;Here's how to implement it correctly.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Implementation
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;QLM.LicenseLib&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;RunLicenseCheck&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;QlmLicense&lt;/span&gt; &lt;span class="n"&gt;license&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;QlmLicense&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;license&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;DefineProduct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"MyApp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"DemoKey"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;license&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CommunicationEncryptionKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"{YourEncryptionKey}"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;license&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ServerUrl&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"https://qlm3.net/qlmdemo/qlmservice/qlmservice.asmx"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;licenseKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;activationKey&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;license&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ReadKeys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;out&lt;/span&gt; &lt;span class="n"&gt;licenseKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;out&lt;/span&gt; &lt;span class="n"&gt;activationKey&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;license&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ValidateLicenseAtStartup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;licenseKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;out&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;MessageBox&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Show&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"License error: "&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"License Required"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A few things worth noting about this code. &lt;code&gt;DefineProduct&lt;/code&gt; is always the first call — it registers your application identity with the QLM system. &lt;code&gt;ReadKeys&lt;/code&gt; retrieves whatever credentials were stored locally after the last activation. The response string returned by each method is human-readable and can be surfaced directly to users, which saves you from writing your own error message layer.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Goes Wrong in Practice
&lt;/h2&gt;

&lt;p&gt;The most common mistake is treating a &lt;code&gt;false&lt;/code&gt; return value as a generic failure. QLM gives you a detailed response string every time — use it. Log it, show it to the user, or at minimum inspect it during debugging. Silent failures are how license bypasses go unnoticed for months.&lt;/p&gt;

&lt;p&gt;The second most common mistake is skipping &lt;code&gt;StoreKeys&lt;/code&gt; after a successful activation. If you don't store the keys, users have to re-activate every time they launch the app.&lt;/p&gt;

&lt;h2&gt;
  
  
  Supported Platforms
&lt;/h2&gt;

&lt;p&gt;QLM works across the environments your users actually run on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Windows: .NET Framework 2.x / 4.x, .NET 6/7/8/9/10&lt;/li&gt;
&lt;li&gt;Cross-platform: .NET 6/7/8/9/10, macOS, Linux&lt;/li&gt;
&lt;li&gt;Mobile: Android, iOS (.NET MAUI, Xamarin)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Pricing
&lt;/h2&gt;

&lt;p&gt;QLM is available in three tiers — Express at $200/year, Professional at $699/year, and Enterprise at $999/year — all per developer/administrator, billed annually. There's a &lt;a href="https://soraco.co/quick-license-manager/qlm-downloads/" rel="noopener noreferrer"&gt;30-day trial&lt;/a&gt; if you want to test it first.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://soraco.co" rel="noopener noreferrer"&gt;Quick License Manager&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://soraco.co/quick-license-manager/quick-license-manager-features/" rel="noopener noreferrer"&gt;Features&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://soraco.co/pricing/" rel="noopener noreferrer"&gt;Pricing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.soraco.co" rel="noopener noreferrer"&gt;Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.soraco.co/docs/api-reference/iqlmlicense/validatelicenseatstartup" rel="noopener noreferrer"&gt;API reference&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>dotnet</category>
      <category>licensing</category>
      <category>csharp</category>
      <category>security</category>
    </item>
    <item>
      <title>Online License Activation in .NET with Quick License Manager</title>
      <dc:creator>Soraco Technologies</dc:creator>
      <pubDate>Fri, 27 Feb 2026 02:41:41 +0000</pubDate>
      <link>https://forem.com/soraco-technologies/online-license-activation-in-net-with-quick-license-manager-m07</link>
      <guid>https://forem.com/soraco-technologies/online-license-activation-in-net-with-quick-license-manager-m07</guid>
      <description>&lt;p&gt;Most .NET developers reach for license validation as an afterthought — but getting it right from the start saves a lot of pain. &lt;a href="https://soraco.co" rel="noopener noreferrer"&gt;Quick License Manager (QLM)&lt;/a&gt; by Soraco Technologies handles the heavy lifting with a straightforward API that works across Windows, macOS, Linux, and mobile.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;Before writing any code, &lt;a href="https://soraco.co/quick-license-manager/qlm-downloads/" rel="noopener noreferrer"&gt;download QLM&lt;/a&gt; and add the SDK reference to your .NET project. QLM supports .NET Framework 2.x/4.x and .NET 6 through 10, so it works with both legacy and modern applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementation
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;QLM.LicenseLib&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;ActivateLicenseOnline&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;licenseKey&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;QlmLicense&lt;/span&gt; &lt;span class="n"&gt;license&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;QlmLicense&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;license&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;DefineProduct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"MyApp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"DemoKey"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;license&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CommunicationEncryptionKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"{YourEncryptionKey}"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;license&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ServerUrl&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"https://qlm3.net/qlmdemo/qlmservice/qlmservice.asmx"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;license&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ActivateLicense&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;licenseKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Environment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MachineName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;out&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;MessageBox&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Show&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Activation failed: "&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Error"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;QlmLicense&lt;/code&gt; class is the main entry point. You call &lt;code&gt;DefineProduct&lt;/code&gt; once with your product ID, major version, minor version, and encryption key. From there, &lt;code&gt;ReadKeys&lt;/code&gt; pulls stored credentials from the registry, and the appropriate API method — &lt;code&gt;ValidateLicenseAtStartup&lt;/code&gt;, &lt;code&gt;ActivateLicense&lt;/code&gt;, or &lt;code&gt;DeactivateLicense&lt;/code&gt; — communicates with your license server and returns a bool plus a human-readable response string.&lt;/p&gt;

&lt;h2&gt;
  
  
  Error Handling
&lt;/h2&gt;

&lt;p&gt;Always check the response string when a call returns false. QLM returns detailed error codes and messages that tell you exactly what went wrong — whether it's a network issue, an expired key, or a seat count limit. Surface these messages directly to users so they know what to do next.&lt;/p&gt;

&lt;h2&gt;
  
  
  Supported Platforms
&lt;/h2&gt;

&lt;p&gt;QLM works across the environments your users actually run:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Windows: .NET Framework 2.x / 4.x, .NET 6/7/8/9/10&lt;/li&gt;
&lt;li&gt;Cross-platform: .NET 6/7/8/9/10, macOS, Linux&lt;/li&gt;
&lt;li&gt;Mobile: Android, iOS (.NET MAUI, Xamarin)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Pricing
&lt;/h2&gt;

&lt;p&gt;QLM Express is $200/year, Professional is $699/year, and Enterprise is $999/year — all per developer/administrator. You can &lt;a href="https://soraco.co/pricing/" rel="noopener noreferrer"&gt;compare plans&lt;/a&gt; or start with the 30-day trial.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://soraco.co" rel="noopener noreferrer"&gt;Quick License Manager&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://soraco.co/quick-license-manager/qlm-downloads/" rel="noopener noreferrer"&gt;Download &amp;amp; Trial&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://soraco.co/quick-license-manager/quick-license-manager-features/" rel="noopener noreferrer"&gt;All Features&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.soraco.co" rel="noopener noreferrer"&gt;Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.soraco.co/docs/api-reference/iqlmlicense/activatelicense" rel="noopener noreferrer"&gt;API Reference for this topic&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>dotnet</category>
      <category>licensing</category>
      <category>csharp</category>
      <category>qlm</category>
    </item>
    <item>
      <title>Offline License Activation in .NET: No Internet Required</title>
      <dc:creator>Soraco Technologies</dc:creator>
      <pubDate>Wed, 25 Feb 2026 04:55:26 +0000</pubDate>
      <link>https://forem.com/soraco-technologies/offline-license-activation-in-net-no-internet-required-3gla</link>
      <guid>https://forem.com/soraco-technologies/offline-license-activation-in-net-no-internet-required-3gla</guid>
      <description>&lt;p&gt;Not all users have internet access when activating software. Air-gapped systems, secure networks, and offline environments require a different activation approach. Quick License Manager (QLM) supports offline activation out of the box.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem with Online-Only Activation
&lt;/h2&gt;

&lt;p&gt;Online activation requires an active internet connection, access to a license server, and real-time validation. This fails for military and government systems, industrial control systems, healthcare devices (HIPAA compliance), secure research facilities, and remote locations without connectivity.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Offline Activation Works
&lt;/h2&gt;

&lt;p&gt;The offline activation workflow is simple:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;User gets Computer ID from your application&lt;/li&gt;
&lt;li&gt;User visits activation portal (on a different connected computer)&lt;/li&gt;
&lt;li&gt;Portal generates Computer Key bound to that Computer ID&lt;/li&gt;
&lt;li&gt;User enters Computer Key back into your application&lt;/li&gt;
&lt;li&gt;Application validates offline using the Computer Key&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;No internet required on the target machine!&lt;/p&gt;

&lt;h2&gt;
  
  
  Get Computer ID
&lt;/h2&gt;

&lt;p&gt;First, display the Computer ID to the user:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;QLM.LicenseLib&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;lv&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;LicenseValidator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"settings.xml"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;computerID&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Empty&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;lv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;QlmLicenseObject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetComputerID&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;ELicenseBinding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ComputerName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="k"&gt;ref&lt;/span&gt; &lt;span class="n"&gt;computerID&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"=== OFFLINE ACTIVATION ==="&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Computer ID: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;computerID&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"\nTo activate:"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"1. Visit: https://yourcompany.com/activate"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"2. Enter your activation key"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"3. Enter this Computer ID"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"4. Copy the Computer Key you receive"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"5. Enter it below"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"\nEnter Computer Key: "&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;computerKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ReadLine&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="nf"&gt;ValidateOfflineLicense&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lv&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;computerID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;computerKey&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;ValidateOfflineLicense&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;LicenseValidator&lt;/span&gt; &lt;span class="n"&gt;lv&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;computerID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;computerKey&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;activationKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"XXXXX-XXXXX-XXXXX-XXXXX-XXXXX"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;needsActivation&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;errorMsg&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Empty&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;isValid&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;QlmLicenseObject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ValidateLicense&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;activationKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;computerKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="k"&gt;ref&lt;/span&gt; &lt;span class="n"&gt;computerID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;ELicenseBinding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ComputerName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="k"&gt;ref&lt;/span&gt; &lt;span class="n"&gt;needsActivation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="k"&gt;ref&lt;/span&gt; &lt;span class="n"&gt;errorMsg&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;isValid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;lv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;QlmLicenseObject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;StoreKeys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;activationKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;computerKey&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"✓ License activated successfully!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"✗ Activation failed: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;errorMsg&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Windows Forms Dialog
&lt;/h2&gt;

&lt;p&gt;Show a user-friendly activation dialog:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Windows.Forms&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;QLM.LicenseLib&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OfflineActivationForm&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Form&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;TextBox&lt;/span&gt; &lt;span class="n"&gt;txtComputerID&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;TextBox&lt;/span&gt; &lt;span class="n"&gt;txtActivationKey&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;TextBox&lt;/span&gt; &lt;span class="n"&gt;txtComputerKey&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;Button&lt;/span&gt; &lt;span class="n"&gt;btnActivate&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;LicenseValidator&lt;/span&gt; &lt;span class="n"&gt;lv&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;OfflineActivationForm&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Text&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Offline Activation"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;Width&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;500&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;Height&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;300&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="n"&gt;lv&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;LicenseValidator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"settings.xml"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;lblInfo&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Label&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Text&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"No internet connection detected.\n"&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt;
                   &lt;span class="s"&gt;"Please use offline activation:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;AutoSize&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;Top&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;Left&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;20&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;lblComputerID&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Label&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Text&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Computer ID:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;Top&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;Left&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;Width&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;

        &lt;span class="n"&gt;txtComputerID&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;TextBox&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Top&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;Left&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;130&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;Width&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;320&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;ReadOnly&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;

        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;computerID&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Empty&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;lv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;QlmLicenseObject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetComputerID&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;ELicenseBinding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ComputerName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="k"&gt;ref&lt;/span&gt; &lt;span class="n"&gt;computerID&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;txtComputerID&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Text&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;computerID&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;lblActivationKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Label&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Text&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Activation Key:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;Top&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;Left&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;Width&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;

        &lt;span class="n"&gt;txtActivationKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;TextBox&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Top&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;Left&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;130&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;Width&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;320&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;lblComputerKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Label&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Text&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Computer Key:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;Top&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;140&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;Left&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;Width&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;

        &lt;span class="n"&gt;txtComputerKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;TextBox&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Top&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;140&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;Left&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;130&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;Width&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;320&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;

        &lt;span class="n"&gt;btnActivate&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Button&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Text&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Activate"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;Top&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;180&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;Left&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;130&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;Width&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;
        &lt;span class="n"&gt;btnActivate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Click&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;BtnActivate_Click&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;lblInstructions&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Label&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Text&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Visit https://yourcompany.com/activate to get Computer Key"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;AutoSize&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;Top&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;220&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;Left&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;20&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;

        &lt;span class="n"&gt;Controls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lblInfo&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Controls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lblComputerID&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Controls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;txtComputerID&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Controls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lblActivationKey&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Controls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;txtActivationKey&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Controls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lblComputerKey&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Controls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;txtComputerKey&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Controls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;btnActivate&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Controls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lblInstructions&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;BtnActivate_Click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;object&lt;/span&gt; &lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;EventArgs&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;computerID&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;txtComputerID&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;activationKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;txtActivationKey&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;computerKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;txtComputerKey&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;needsActivation&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;errorMsg&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Empty&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;isValid&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;QlmLicenseObject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ValidateLicense&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;activationKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;computerKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="k"&gt;ref&lt;/span&gt; &lt;span class="n"&gt;computerID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;ELicenseBinding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ComputerName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="k"&gt;ref&lt;/span&gt; &lt;span class="n"&gt;needsActivation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="k"&gt;ref&lt;/span&gt; &lt;span class="n"&gt;errorMsg&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;isValid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;lv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;QlmLicenseObject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;StoreKeys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;activationKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;computerKey&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;MessageBox&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Show&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"License activated successfully!"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                &lt;span class="s"&gt;"Success"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MessageBoxButtons&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OK&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                &lt;span class="n"&gt;MessageBoxIcon&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Information&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="nf"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;MessageBox&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Show&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Activation failed:\n&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;errorMsg&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                &lt;span class="s"&gt;"Error"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MessageBoxButtons&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OK&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                &lt;span class="n"&gt;MessageBoxIcon&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Self-Service Portal
&lt;/h2&gt;

&lt;p&gt;QLM includes a built-in Self-Help Customer Site that generates Computer Keys automatically. The user workflow is straightforward: visit the portal, enter the Activation Key and Computer ID, click Activate, and receive the Computer Key instantly. No manual intervention needed. The portal validates the Activation Key, checks activation limits, and generates the Computer Key on the spot.&lt;/p&gt;

&lt;h2&gt;
  
  
  Best Practices
&lt;/h2&gt;

&lt;p&gt;For security, the Computer ID should be unique and stable. Use &lt;code&gt;ELicenseBinding.ComputerName&lt;/code&gt; for most cases, or consider &lt;code&gt;ELicenseBinding.MacAddress&lt;/code&gt; for hardware binding.&lt;/p&gt;

&lt;p&gt;For user experience, show clear step-by-step instructions, provide the portal URL prominently, add a "Copy to Clipboard" button for the Computer ID, and validate the format before submission.&lt;/p&gt;

&lt;p&gt;For testing, verify the solution on a disconnected machine, check that Computer ID remains stable after reboot, test activation limit enforcement, and review error messages for clarity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Platform Support
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Windows: .NET Framework 2.x/4.x, .NET 6/7/8/9/10&lt;/li&gt;
&lt;li&gt;Cross-platform: .NET 6/7/8/9/10, macOS, Linux&lt;/li&gt;
&lt;li&gt;Mobile: Android, iOS (.NET MAUI, Xamarin)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Learn More
&lt;/h2&gt;

&lt;p&gt;QLM Documentation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.soraco.co/docs/fundamental-concepts/how-does-offline-activation-work" rel="noopener noreferrer"&gt;Offline Activation Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.soraco.co/docs/self-help-customer-site" rel="noopener noreferrer"&gt;Self-Help Customer Site&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.soraco.co/docs/api-reference/.net-api" rel="noopener noreferrer"&gt;API Reference&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Quick License Manager:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://soraco.co/quick-license-manager/qlm-downloads/" rel="noopener noreferrer"&gt;Download 30-day trial&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://soraco.co/quick-license-manager/quick-license-manager-features/" rel="noopener noreferrer"&gt;Features&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://soraco.co/pricing/" rel="noopener noreferrer"&gt;Pricing&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Pricing (per developer/administrator):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;QLM Express: $200/year&lt;/li&gt;
&lt;li&gt;QLM Professional: $699/year&lt;/li&gt;
&lt;li&gt;QLM Enterprise: $999/year&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Offline activation solves the air-gap problem elegantly. Users can activate without internet, and you maintain full license control. Implement offline licensing with &lt;a href="https://soraco.co" rel="noopener noreferrer"&gt;Quick License Manager&lt;/a&gt; by Soraco Technologies.&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>csharp</category>
      <category>licensing</category>
      <category>security</category>
    </item>
    <item>
      <title>How to Check if a .NET License is Activated in 5 Lines of Code</title>
      <dc:creator>Soraco Technologies</dc:creator>
      <pubDate>Mon, 23 Feb 2026 14:04:22 +0000</pubDate>
      <link>https://forem.com/soraco-technologies/how-to-check-if-a-net-license-is-activated-in-5-lines-of-code-26lp</link>
      <guid>https://forem.com/soraco-technologies/how-to-check-if-a-net-license-is-activated-in-5-lines-of-code-26lp</guid>
      <description>&lt;p&gt;Your .NET app needs to know: &lt;strong&gt;Is there a valid license on this computer?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here's how to check in 5 lines.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Code
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;QLM.LicenseLib&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;lv&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;LicenseValidator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"settings.xml"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;needsActivation&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;errorMsg&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Empty&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;isActivated&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ValidateLicenseAtStartup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;ELicenseBinding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ComputerName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;ref&lt;/span&gt; &lt;span class="n"&gt;needsActivation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;ref&lt;/span&gt; &lt;span class="n"&gt;errorMsg&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;isActivated&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"License is valid - app can run"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"No valid license: "&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;errorMsg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. 5 lines.&lt;/p&gt;

&lt;h2&gt;
  
  
  What ValidateLicenseAtStartup Does
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Looks for stored license&lt;/strong&gt; on the computer&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Validates signature&lt;/strong&gt; (RSA-2048)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Checks expiry&lt;/strong&gt; (for trials/subscriptions)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Optionally contacts server&lt;/strong&gt; (if online validation enabled)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Returns true/false&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Three Possible Outcomes
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. License is valid (&lt;code&gt;isActivated = true&lt;/code&gt;)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;isActivated&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;RunApp&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. No license found (&lt;code&gt;needsActivation = true&lt;/code&gt;)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;needsActivation&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;ShowActivationDialog&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. License exists but invalid (&lt;code&gt;isActivated = false&lt;/code&gt;)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;isActivated&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error: "&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;errorMsg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// Expired, wrong version, revoked, etc.&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Real Example: Desktop App
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;QLM.LicenseLib&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;IsLicenseActivated&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Starting application..."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="nf"&gt;RunApp&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Please activate your license."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;IsLicenseActivated&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;lv&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;LicenseValidator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"settings.xml"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;needsActivation&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;errorMsg&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Empty&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;isValid&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ValidateLicenseAtStartup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;ELicenseBinding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ComputerName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="k"&gt;ref&lt;/span&gt; &lt;span class="n"&gt;needsActivation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="k"&gt;ref&lt;/span&gt; &lt;span class="n"&gt;errorMsg&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;needsActivation&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"No license found - activation required"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;isValid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"License invalid: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;errorMsg&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;RunApp&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"App is running with valid license"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// Your application code here&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Different License Types
&lt;/h2&gt;

&lt;p&gt;This works for all license types:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Permanent licenses:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No expiry date&lt;/li&gt;
&lt;li&gt;Valid forever&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Trial licenses:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Expires after X days&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ValidateLicenseAtStartup&lt;/code&gt; returns false after expiry&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Subscription licenses:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Renews periodically&lt;/li&gt;
&lt;li&gt;Auto-extends when customer pays&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Hardware Binding
&lt;/h2&gt;

&lt;p&gt;You can bind licenses to different identifiers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Computer Name (default)&lt;/span&gt;
&lt;span class="n"&gt;lv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ValidateLicenseAtStartup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;ELicenseBinding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ComputerName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;ref&lt;/span&gt; &lt;span class="n"&gt;needsActivation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;ref&lt;/span&gt; &lt;span class="n"&gt;errorMsg&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// MAC Address&lt;/span&gt;
&lt;span class="n"&gt;lv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ValidateLicenseAtStartup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;ELicenseBinding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MacAddress&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;ref&lt;/span&gt; &lt;span class="n"&gt;needsActivation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;ref&lt;/span&gt; &lt;span class="n"&gt;errorMsg&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Motherboard Serial&lt;/span&gt;
&lt;span class="n"&gt;lv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ValidateLicenseAtStartup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;ELicenseBinding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MotherboardSerialNumber&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;ref&lt;/span&gt; &lt;span class="n"&gt;needsActivation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;ref&lt;/span&gt; &lt;span class="n"&gt;errorMsg&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Most common:&lt;/strong&gt; ComputerName (easy for users)&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Most secure:&lt;/strong&gt; MotherboardSerialNumber (survives OS reinstalls)&lt;/p&gt;
&lt;h2&gt;
  
  
  Offline vs Online Validation
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Offline (default):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Validates license signature locally&lt;/li&gt;
&lt;li&gt;Checks expiry date&lt;/li&gt;
&lt;li&gt;No internet required&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Online (optional):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Contacts QLM License Server&lt;/li&gt;
&lt;li&gt;Detects revoked licenses&lt;/li&gt;
&lt;li&gt;Checks for subscription renewals&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Enable online validation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;lv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;QlmLicenseObject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ValidateOnServer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  When to Call This
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;At application startup:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(!&lt;/span&gt;&lt;span class="nf"&gt;IsLicenseActivated&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Environment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;RunApp&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Before accessing paid features:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;UnlockPremiumFeature&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(!&lt;/span&gt;&lt;span class="nf"&gt;IsLicenseActivated&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;MessageBox&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Show&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"This feature requires a license"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Premium feature code&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Error Messages
&lt;/h2&gt;

&lt;p&gt;Common &lt;code&gt;errorMsg&lt;/code&gt; values:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;"The license key is invalid"&lt;/code&gt; → Wrong key or signature&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;"The license has expired"&lt;/code&gt; → Trial/subscription ended&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;"The license is disabled"&lt;/code&gt; → Revoked by admin&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;"The product version is incorrect"&lt;/code&gt; → License for different version&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Supported Platforms
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Windows: .NET Framework 2.x / 4.x, .NET 6/7/8/9/10&lt;/li&gt;
&lt;li&gt;Cross-platform: .NET 6/7/8/9/10 (macOS, Linux)&lt;/li&gt;
&lt;li&gt;Mobile: Android, iOS (.NET MAUI, Xamarin)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Quick License Manager
&lt;/h2&gt;

&lt;p&gt;This uses &lt;a href="https://soraco.co" rel="noopener noreferrer"&gt;Quick License Manager (QLM)&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pricing (per developer):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;QLM Express: $200/year&lt;/li&gt;
&lt;li&gt;QLM Professional: $699/year&lt;/li&gt;
&lt;li&gt;QLM Enterprise: $999/year&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Features:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;RSA-2048 + AES-256 encryption&lt;/li&gt;
&lt;li&gt;Online &amp;amp; offline activation&lt;/li&gt;
&lt;li&gt;Trial &amp;amp; subscription support&lt;/li&gt;
&lt;li&gt;12 e-commerce integrations&lt;/li&gt;
&lt;li&gt;Customer self-service portal&lt;/li&gt;
&lt;li&gt;Floating licenses (Enterprise)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://soraco.co/quick-license-manager/qlm-downloads/" rel="noopener noreferrer"&gt;Download 30-day trial&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://soraco.co" rel="noopener noreferrer"&gt;Quick License Manager&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://soraco.co/quick-license-manager/quick-license-manager-features/" rel="noopener noreferrer"&gt;Features&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://soraco.co/pricing/" rel="noopener noreferrer"&gt;Pricing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://soraco.co/courses/qlm-tutorials/" rel="noopener noreferrer"&gt;Tutorials&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.soraco.co" rel="noopener noreferrer"&gt;Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.soraco.co/docs/api-reference/.net-api/licensevalidator/methods/validatelicenseatstartup" rel="noopener noreferrer"&gt;ValidateLicenseAtStartup API&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Related articles:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/olivier_moussalli_e3492f5/hardware-binding-in-c-choosing-the-right-computer-locking-strategy-1ood"&gt;Hardware Binding Strategies&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/olivier_moussalli_e3492f5/trial-license-strategies-converting-40-more-users-to-paid-customers"&gt;Trial License Strategies&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/olivier_moussalli_e3492f5/automated-license-distribution-from-purchase-to-activation-in-60-seconds-2hii"&gt;E-Commerce Automation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Questions? Drop them in the comments!&lt;/strong&gt; 👇&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Quick License Manager by Soraco Technologies — &lt;a href="https://soraco.co" rel="noopener noreferrer"&gt;https://soraco.co&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>csharp</category>
      <category>licensing</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Embedded Trial Keys in .NET: Ship Evaluation Versions Without a Server</title>
      <dc:creator>Soraco Technologies</dc:creator>
      <pubDate>Fri, 20 Feb 2026 15:59:54 +0000</pubDate>
      <link>https://forem.com/soraco-technologies/embedded-trial-keys-in-net-ship-evaluation-versions-without-a-server-3joj</link>
      <guid>https://forem.com/soraco-technologies/embedded-trial-keys-in-net-ship-evaluation-versions-without-a-server-3joj</guid>
      <description>&lt;p&gt;You want to ship a trial version of your app. Here's the easiest way: &lt;strong&gt;embed a trial key directly in the code&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;No server. No activation. Just works.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Embedded Trial Keys?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Traditional trial approach:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;User downloads app&lt;/li&gt;
&lt;li&gt;User registers on your website&lt;/li&gt;
&lt;li&gt;You email a trial key&lt;/li&gt;
&lt;li&gt;User enters key in app&lt;/li&gt;
&lt;li&gt;App validates online&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Result:&lt;/strong&gt; 30-40% of users drop off before trying your app.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Embedded trial approach:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;User downloads app&lt;/li&gt;
&lt;li&gt;App runs immediately (trial key embedded)&lt;/li&gt;
&lt;li&gt;User evaluates&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Result:&lt;/strong&gt; 100% trial start rate.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Create a Trial Key
&lt;/h2&gt;

&lt;p&gt;In QLM Management Console:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Manage Keys → Create
2. Product: [Your Product]
3. License Model: Trial
4. Expiry Date: 30 days from today
5. Number of Licenses: 1
6. Click OK
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copy the generated key (example: &lt;code&gt;A5B3C-D8E2F-G1H4I-J7K9L-M3N6P&lt;/code&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Embed the Key
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;QLM.LicenseLib&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Embedded trial key - same for all users&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;TRIAL_KEY&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"A5B3C-D8E2F-G1H4I-J7K9L-M3N6P"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;ValidateLicense&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Trial active - running app"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="nf"&gt;RunApp&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Trial expired or invalid"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;ValidateLicense&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;lv&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;LicenseValidator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"settings.xml"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;needsActivation&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;errorMsg&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Empty&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;// First check if license exists locally&lt;/span&gt;
        &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;isValid&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ValidateLicenseAtStartup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;ELicenseBinding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ComputerName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="k"&gt;ref&lt;/span&gt; &lt;span class="n"&gt;needsActivation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="k"&gt;ref&lt;/span&gt; &lt;span class="n"&gt;errorMsg&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// If no license found, use embedded trial key&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;isValid&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsNullOrEmpty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ActivationKey&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;lv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ActivationKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;TRIAL_KEY&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="n"&gt;lv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ComputerKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Empty&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

            &lt;span class="n"&gt;isValid&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ValidateLicenseAtStartup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="n"&gt;ELicenseBinding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ComputerName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="k"&gt;ref&lt;/span&gt; &lt;span class="n"&gt;needsActivation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="k"&gt;ref&lt;/span&gt; &lt;span class="n"&gt;errorMsg&lt;/span&gt;
            &lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;isValid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="c1"&gt;// Store trial key locally for next run&lt;/span&gt;
                &lt;span class="n"&gt;lv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;QlmLicenseObject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;StoreKeys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ActivationKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ComputerKey&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Trial started - 30 days remaining"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;isValid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;RunApp&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Your application code here&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How It Works
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;First run:&lt;/strong&gt; App checks for local license → none found&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;App uses embedded key:&lt;/strong&gt; Validates it against expiry date&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Trial starts:&lt;/strong&gt; Key stored locally, expiry date locked&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Subsequent runs:&lt;/strong&gt; App uses stored license&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;After 30 days:&lt;/strong&gt; License expires, app stops working&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; The trial period starts on &lt;strong&gt;first use&lt;/strong&gt;, not when you create the key. The expiry date is calculated from first validation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Upgrade Path
&lt;/h2&gt;

&lt;p&gt;When the user purchases, they get a &lt;strong&gt;permanent key&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// User enters purchased key via QLM License Wizard&lt;/span&gt;
&lt;span class="c1"&gt;// Wizard replaces trial key with permanent key&lt;/span&gt;
&lt;span class="c1"&gt;// App validates and works indefinitely&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Show Days Remaining
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;ShowTrialStatus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;LicenseValidator&lt;/span&gt; &lt;span class="n"&gt;lv&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;QlmLicenseObject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LicenseModel&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;ELicenseModel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;trial&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;DateTime&lt;/span&gt; &lt;span class="n"&gt;expiryDate&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;QlmLicenseObject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ExpiryDate&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;daysLeft&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;expiryDate&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;Days&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;daysLeft&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Trial: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;daysLeft&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; days remaining"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Trial expired"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Alternative: Different Key Per User
&lt;/h2&gt;

&lt;p&gt;If you want to track each download:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Generate trial key server-side when user downloads&lt;/span&gt;
&lt;span class="c1"&gt;// Embed unique key per user&lt;/span&gt;
&lt;span class="c1"&gt;// Track which keys are activated&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But this requires a server call. The embedded approach is simpler.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pros &amp;amp; Cons
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Pros:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ Zero friction — app runs immediately&lt;/li&gt;
&lt;li&gt;✅ No server required for trial&lt;/li&gt;
&lt;li&gt;✅ Works offline&lt;/li&gt;
&lt;li&gt;✅ Same binary for trial &amp;amp; paid&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;❌ Can't track who tries your app&lt;/li&gt;
&lt;li&gt;❌ Key can be extracted (not a real issue for trials)&lt;/li&gt;
&lt;li&gt;❌ One key for all users (acceptable for trials)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  When to Use This
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Use embedded keys when:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Frictionless trial is priority #1&lt;/li&gt;
&lt;li&gt;You don't need to track trial users&lt;/li&gt;
&lt;li&gt;You want offline trial support&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Don't use when:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You need to track every download&lt;/li&gt;
&lt;li&gt;You want unique keys per user&lt;/li&gt;
&lt;li&gt;You need trial usage analytics&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Supported Platforms
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Windows: .NET Framework 2.x / 4.x, .NET 6/7/8/9/10&lt;/li&gt;
&lt;li&gt;Cross-platform: .NET 6/7/8/9/10 (macOS, Linux)&lt;/li&gt;
&lt;li&gt;Mobile: Android, iOS (.NET MAUI, Xamarin)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Quick License Manager
&lt;/h2&gt;

&lt;p&gt;This uses &lt;a href="https://soraco.co" rel="noopener noreferrer"&gt;Quick License Manager (QLM)&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pricing (per developer):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;QLM Express: $200/year&lt;/li&gt;
&lt;li&gt;QLM Professional: $699/year&lt;/li&gt;
&lt;li&gt;QLM Enterprise: $999/year&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://soraco.co/quick-license-manager/qlm-downloads/" rel="noopener noreferrer"&gt;Download 30-day trial&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://soraco.co" rel="noopener noreferrer"&gt;Quick License Manager&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://soraco.co/quick-license-manager/quick-license-manager-features/" rel="noopener noreferrer"&gt;Features&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://soraco.co/pricing/" rel="noopener noreferrer"&gt;Pricing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://soraco.co/courses/qlm-tutorials/" rel="noopener noreferrer"&gt;Tutorials&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.soraco.co" rel="noopener noreferrer"&gt;Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.soraco.co/docs/how-to/how-to-ship-an-evaluation-version-of-your-software" rel="noopener noreferrer"&gt;How to ship an evaluation version&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.soraco.co/docs/how-to/how-to-generate-a-trial-key-for-your-application" rel="noopener noreferrer"&gt;How to generate trial keys&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Related articles:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/olivier_moussalli_e3492f5"&gt;Basic License Validation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/olivier_moussalli_e3492f5/trial-license-strategies-converting-40-more-users-to-paid-customers"&gt;Trial License Strategies&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/olivier_moussalli_e3492f5/automated-license-distribution-from-purchase-to-activation-in-60-seconds-2hii"&gt;E-Commerce Automation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;How do you handle trials in your apps? Share in the comments!&lt;/strong&gt; 👇&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Quick License Manager by Soraco Technologies — &lt;a href="https://soraco.co" rel="noopener noreferrer"&gt;https://soraco.co&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>csharp</category>
      <category>trial</category>
      <category>licensing</category>
    </item>
    <item>
      <title>Embedded Trial Keys in .NET: Ship Evaluation Versions Without a Server</title>
      <dc:creator>Soraco Technologies</dc:creator>
      <pubDate>Thu, 19 Feb 2026 15:27:02 +0000</pubDate>
      <link>https://forem.com/soraco-technologies/embedded-trial-keys-in-net-ship-evaluation-versions-without-a-server-5341</link>
      <guid>https://forem.com/soraco-technologies/embedded-trial-keys-in-net-ship-evaluation-versions-without-a-server-5341</guid>
      <description>&lt;p&gt;You want to ship a trial version of your app. Here's the easiest way: &lt;strong&gt;embed a trial key directly in the code&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;No server. No activation. Just works.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Embedded Trial Keys?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Traditional trial approach:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;User downloads app&lt;/li&gt;
&lt;li&gt;User registers on your website&lt;/li&gt;
&lt;li&gt;You email a trial key&lt;/li&gt;
&lt;li&gt;User enters key in app&lt;/li&gt;
&lt;li&gt;App validates online&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Result:&lt;/strong&gt; 30-40% of users drop off before trying your app.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Embedded trial approach:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;User downloads app&lt;/li&gt;
&lt;li&gt;App runs immediately (trial key embedded)&lt;/li&gt;
&lt;li&gt;User evaluates&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Result:&lt;/strong&gt; 100% trial start rate.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Create a Trial Key
&lt;/h2&gt;

&lt;p&gt;In QLM Management Console:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Manage Keys → Create
2. Product: [Your Product]
3. License Model: Trial
4. Expiry Date: 30 days from today
5. Number of Licenses: 1
6. Click OK
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copy the generated key (example: &lt;code&gt;A5B3C-D8E2F-G1H4I-J7K9L-M3N6P&lt;/code&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Embed the Key
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;QLM.LicenseLib&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Embedded trial key - same for all users&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;TRIAL_KEY&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"A5B3C-D8E2F-G1H4I-J7K9L-M3N6P"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;ValidateLicense&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Trial active - running app"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="nf"&gt;RunApp&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Trial expired or invalid"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;ValidateLicense&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;lv&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;LicenseValidator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"settings.xml"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;needsActivation&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;errorMsg&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Empty&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;// First check if license exists locally&lt;/span&gt;
        &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;isValid&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ValidateLicenseAtStartup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;ELicenseBinding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ComputerName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="k"&gt;ref&lt;/span&gt; &lt;span class="n"&gt;needsActivation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="k"&gt;ref&lt;/span&gt; &lt;span class="n"&gt;errorMsg&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// If no license found, use embedded trial key&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;isValid&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsNullOrEmpty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ActivationKey&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;lv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ActivationKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;TRIAL_KEY&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="n"&gt;lv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ComputerKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Empty&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

            &lt;span class="n"&gt;isValid&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ValidateLicenseAtStartup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="n"&gt;ELicenseBinding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ComputerName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="k"&gt;ref&lt;/span&gt; &lt;span class="n"&gt;needsActivation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="k"&gt;ref&lt;/span&gt; &lt;span class="n"&gt;errorMsg&lt;/span&gt;
            &lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;isValid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="c1"&gt;// Store trial key locally for next run&lt;/span&gt;
                &lt;span class="n"&gt;lv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;QlmLicenseObject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;StoreKeys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ActivationKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ComputerKey&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Trial started - 30 days remaining"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;isValid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;RunApp&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Your application code here&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How It Works
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;First run:&lt;/strong&gt; App checks for local license → none found&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;App uses embedded key:&lt;/strong&gt; Validates it against expiry date&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Trial starts:&lt;/strong&gt; Key stored locally, expiry date locked&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Subsequent runs:&lt;/strong&gt; App uses stored license&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;After 30 days:&lt;/strong&gt; License expires, app stops working&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; The trial period starts on &lt;strong&gt;first use&lt;/strong&gt;, not when you create the key. The expiry date is calculated from first validation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Upgrade Path
&lt;/h2&gt;

&lt;p&gt;When the user purchases, they get a &lt;strong&gt;permanent key&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// User enters purchased key via QLM License Wizard&lt;/span&gt;
&lt;span class="c1"&gt;// Wizard replaces trial key with permanent key&lt;/span&gt;
&lt;span class="c1"&gt;// App validates and works indefinitely&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Show Days Remaining
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;ShowTrialStatus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;LicenseValidator&lt;/span&gt; &lt;span class="n"&gt;lv&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;QlmLicenseObject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LicenseModel&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;ELicenseModel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;trial&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;DateTime&lt;/span&gt; &lt;span class="n"&gt;expiryDate&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;QlmLicenseObject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ExpiryDate&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;daysLeft&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;expiryDate&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;Days&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;daysLeft&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Trial: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;daysLeft&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; days remaining"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Trial expired"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Alternative: Different Key Per User
&lt;/h2&gt;

&lt;p&gt;If you want to track each download:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Generate trial key server-side when user downloads&lt;/span&gt;
&lt;span class="c1"&gt;// Embed unique key per user&lt;/span&gt;
&lt;span class="c1"&gt;// Track which keys are activated&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But this requires a server call. The embedded approach is simpler.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pros &amp;amp; Cons
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Pros:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ Zero friction — app runs immediately&lt;/li&gt;
&lt;li&gt;✅ No server required for trial&lt;/li&gt;
&lt;li&gt;✅ Works offline&lt;/li&gt;
&lt;li&gt;✅ Same binary for trial &amp;amp; paid&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;❌ Can't track who tries your app&lt;/li&gt;
&lt;li&gt;❌ Key can be extracted (not a real issue for trials)&lt;/li&gt;
&lt;li&gt;❌ One key for all users (acceptable for trials)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  When to Use This
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Use embedded keys when:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Frictionless trial is priority #1&lt;/li&gt;
&lt;li&gt;You don't need to track trial users&lt;/li&gt;
&lt;li&gt;You want offline trial support&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Don't use when:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You need to track every download&lt;/li&gt;
&lt;li&gt;You want unique keys per user&lt;/li&gt;
&lt;li&gt;You need trial usage analytics&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Supported Platforms
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Windows: .NET Framework 2.x / 4.x, .NET 6/7/8/9/10&lt;/li&gt;
&lt;li&gt;Cross-platform: .NET 6/7/8/9/10 (macOS, Linux)&lt;/li&gt;
&lt;li&gt;Mobile: Android, iOS (.NET MAUI, Xamarin)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Quick License Manager
&lt;/h2&gt;

&lt;p&gt;This uses &lt;a href="https://soraco.co" rel="noopener noreferrer"&gt;Quick License Manager (QLM)&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pricing (per developer):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;QLM Express: $200/year&lt;/li&gt;
&lt;li&gt;QLM Professional: $699/year&lt;/li&gt;
&lt;li&gt;QLM Enterprise: $999/year&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://soraco.co/quick-license-manager/qlm-downloads/" rel="noopener noreferrer"&gt;Download 30-day trial&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://soraco.co" rel="noopener noreferrer"&gt;Quick License Manager&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://soraco.co/quick-license-manager/quick-license-manager-features/" rel="noopener noreferrer"&gt;Features&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://soraco.co/pricing/" rel="noopener noreferrer"&gt;Pricing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://soraco.co/courses/qlm-tutorials/" rel="noopener noreferrer"&gt;Tutorials&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.soraco.co" rel="noopener noreferrer"&gt;Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.soraco.co/docs/how-to/how-to-ship-an-evaluation-version-of-your-software" rel="noopener noreferrer"&gt;How to ship an evaluation version&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.soraco.co/docs/how-to/how-to-generate-a-trial-key-for-your-application" rel="noopener noreferrer"&gt;How to generate trial keys&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Related articles:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/olivier_moussalli_e3492f5"&gt;Basic License Validation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/olivier_moussalli_e3492f5/trial-license-strategies-converting-40-more-users-to-paid-customers"&gt;Trial License Strategies&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/olivier_moussalli_e3492f5/automated-license-distribution-from-purchase-to-activation-in-60-seconds-2hii"&gt;E-Commerce Automation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;How do you handle trials in your apps? Share in the comments!&lt;/strong&gt; 👇&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Quick License Manager by Soraco Technologies — &lt;a href="https://soraco.co" rel="noopener noreferrer"&gt;https://soraco.co&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>csharp</category>
      <category>trial</category>
      <category>licensing</category>
    </item>
    <item>
      <title>Basic License Validation in .NET: 10 Lines to Protect Your Application</title>
      <dc:creator>Soraco Technologies</dc:creator>
      <pubDate>Thu, 19 Feb 2026 15:24:44 +0000</pubDate>
      <link>https://forem.com/soraco-technologies/basic-license-validation-in-net-10-lines-to-protect-your-application-ble</link>
      <guid>https://forem.com/soraco-technologies/basic-license-validation-in-net-10-lines-to-protect-your-application-ble</guid>
      <description>&lt;p&gt;Your .NET application needs license protection. Here's the simplest way to add it — 10 lines of code.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;You built a great app. Now you want to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Stop unauthorized copies&lt;/li&gt;
&lt;li&gt;Issue trial licenses&lt;/li&gt;
&lt;li&gt;Track activations&lt;/li&gt;
&lt;li&gt;Manage subscriptions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; Add license validation at startup.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Code
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;QLM.LicenseLib&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;lv&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;LicenseValidator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"settings.xml"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;needsActivation&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;errorMsg&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Empty&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;isValid&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ValidateLicenseAtStartup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;ELicenseBinding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ComputerName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="k"&gt;ref&lt;/span&gt; &lt;span class="n"&gt;needsActivation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="k"&gt;ref&lt;/span&gt; &lt;span class="n"&gt;errorMsg&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;isValid&lt;/span&gt; &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="n"&gt;needsActivation&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"License invalid: "&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;errorMsg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Your app code here&lt;/span&gt;
    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"License valid - running app"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. 10 lines.&lt;/p&gt;

&lt;h2&gt;
  
  
  How It Works
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;ValidateLicenseAtStartup&lt;/code&gt; does 5 things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Looks for a license&lt;/strong&gt; stored locally&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Validates the signature&lt;/strong&gt; (RSA-2048 encryption)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Checks expiry date&lt;/strong&gt; (for trials/subscriptions)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Validates online&lt;/strong&gt; (optional server check)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Returns true/false&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If no license exists, &lt;code&gt;needsActivation&lt;/code&gt; is set to &lt;code&gt;true&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hardware Binding Options
&lt;/h2&gt;

&lt;p&gt;Tie licenses to specific computers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;ELicenseBinding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ComputerName&lt;/span&gt;          &lt;span class="c1"&gt;// Computer name&lt;/span&gt;
&lt;span class="n"&gt;ELicenseBinding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MacAddress&lt;/span&gt;            &lt;span class="c1"&gt;// MAC address&lt;/span&gt;
&lt;span class="n"&gt;ELicenseBinding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MotherboardSerialNumber&lt;/span&gt;  &lt;span class="c1"&gt;// Motherboard&lt;/span&gt;
&lt;span class="n"&gt;ELicenseBinding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HardDiskSerialNumber&lt;/span&gt;     &lt;span class="c1"&gt;// Hard drive&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Most common:&lt;/strong&gt; &lt;code&gt;ComputerName&lt;/code&gt; (easy for users, good enough security)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Most secure:&lt;/strong&gt; &lt;code&gt;MotherboardSerialNumber&lt;/code&gt; (survives OS reinstalls)&lt;/p&gt;

&lt;h2&gt;
  
  
  What About the License Wizard?
&lt;/h2&gt;

&lt;p&gt;You'll want a UI for activation. QLM includes one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;isValid&lt;/span&gt; &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="n"&gt;needsActivation&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Launch QLM License Wizard&lt;/span&gt;
    &lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Diagnostics&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Start&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"QlmLicenseWizard.exe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="s"&gt;"/settings \"settings.xml\""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Re-validate after activation&lt;/span&gt;
    &lt;span class="n"&gt;isValid&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ValidateLicenseAtStartup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;ELicenseBinding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ComputerName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="k"&gt;ref&lt;/span&gt; &lt;span class="n"&gt;needsActivation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="k"&gt;ref&lt;/span&gt; &lt;span class="n"&gt;errorMsg&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The wizard handles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Online activation&lt;/li&gt;
&lt;li&gt;Offline activation&lt;/li&gt;
&lt;li&gt;Trial key entry&lt;/li&gt;
&lt;li&gt;Purchase links&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Real Example: Console App
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;QLM.LicenseLib&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;LicenseValidator&lt;/span&gt; &lt;span class="n"&gt;lv&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;settingsFile&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Demo 1.0.lw.xml"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;ValidateLicense&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;RunApp&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Press any key to exit..."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ReadKey&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;ValidateLicense&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;lv&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;LicenseValidator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;settingsFile&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;needsActivation&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;errorMsg&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Empty&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;isValid&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ValidateLicenseAtStartup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;ELicenseBinding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ComputerName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="k"&gt;ref&lt;/span&gt; &lt;span class="n"&gt;needsActivation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="k"&gt;ref&lt;/span&gt; &lt;span class="n"&gt;errorMsg&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;isValid&lt;/span&gt; &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="n"&gt;needsActivation&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"License validation failed: "&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;errorMsg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Please activate your license."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;RunApp&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"License valid!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Running application..."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// Your app logic here&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Supported Platforms
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Windows: .NET Framework 2.x / 4.x, .NET 6/7/8/9/10&lt;/li&gt;
&lt;li&gt;Cross-platform: .NET 6/7/8/9/10 (macOS, Linux)&lt;/li&gt;
&lt;li&gt;Mobile: Android, iOS (.NET MAUI, Xamarin)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Quick License Manager
&lt;/h2&gt;

&lt;p&gt;This uses &lt;a href="https://soraco.co" rel="noopener noreferrer"&gt;Quick License Manager (QLM)&lt;/a&gt; — the most complete .NET licensing solution.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pricing (per developer):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;QLM Express: $200/year&lt;/li&gt;
&lt;li&gt;QLM Professional: $699/year
&lt;/li&gt;
&lt;li&gt;QLM Enterprise: $999/year&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Features:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;RSA-2048 + AES-256 encryption&lt;/li&gt;
&lt;li&gt;Online &amp;amp; offline activation&lt;/li&gt;
&lt;li&gt;12 e-commerce integrations&lt;/li&gt;
&lt;li&gt;Trial &amp;amp; subscription support&lt;/li&gt;
&lt;li&gt;Floating licenses (Enterprise)&lt;/li&gt;
&lt;li&gt;Customer self-service portal&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://soraco.co/quick-license-manager/qlm-downloads/" rel="noopener noreferrer"&gt;Download 30-day trial&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://soraco.co" rel="noopener noreferrer"&gt;Quick License Manager&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://soraco.co/quick-license-manager/quick-license-manager-features/" rel="noopener noreferrer"&gt;Features&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://soraco.co/pricing/" rel="noopener noreferrer"&gt;Pricing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://soraco.co/courses/qlm-tutorials/" rel="noopener noreferrer"&gt;Tutorials&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.soraco.co" rel="noopener noreferrer"&gt;Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.soraco.co/docs/api-reference/.net-api/licensevalidator/methods/validatelicenseatstartup" rel="noopener noreferrer"&gt;ValidateLicenseAtStartup API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.soraco.co/docs/step-by-step-guides/protect-a-.net-core-console-app" rel="noopener noreferrer"&gt;Protect a .NET Core Console App&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Related articles:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/olivier_moussalli_e3492f5/hardware-binding-in-c-choosing-the-right-computer-locking-strategy-1ood"&gt;Hardware Binding Strategies&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/olivier_moussalli_e3492f5/automated-license-distribution-from-purchase-to-activation-in-60-seconds-2hii"&gt;E-Commerce Automation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/olivier_moussalli_e3492f5/trial-license-strategies-converting-40-more-users-to-paid-customers"&gt;Trial License Strategies&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Got questions about license validation? Drop them in the comments!&lt;/strong&gt; 👇&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Quick License Manager by Soraco Technologies — &lt;a href="https://soraco.co" rel="noopener noreferrer"&gt;https://soraco.co&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>csharp</category>
      <category>licensing</category>
      <category>security</category>
    </item>
    <item>
      <title>Implementing Concurrent User Licensing in .NET: A Floating License Guide</title>
      <dc:creator>Soraco Technologies</dc:creator>
      <pubDate>Mon, 26 Jan 2026 06:27:16 +0000</pubDate>
      <link>https://forem.com/soraco-technologies/implementing-concurrent-user-licensing-in-net-a-floating-license-guide-3l20</link>
      <guid>https://forem.com/soraco-technologies/implementing-concurrent-user-licensing-in-net-a-floating-license-guide-3l20</guid>
      <description>&lt;p&gt;Enterprise software often needs to support concurrent user licensing - where multiple employees share a limited pool of licenses. This guide shows you how to implement floating licenses in your .NET applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Problem Do Floating Licenses Solve?
&lt;/h2&gt;

&lt;p&gt;Imagine selling software to a company with 100 employees, but only 20 use it simultaneously. With traditional node-locked licenses, you'd need to sell 100 licenses. With floating licenses, you sell 20 concurrent-use licenses that any of the 100 employees can access.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The business case:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Customers pay for actual usage, not potential users&lt;/li&gt;
&lt;li&gt;Reduces software costs for enterprises&lt;/li&gt;
&lt;li&gt;Increases your sales to larger organizations&lt;/li&gt;
&lt;li&gt;Prevents license waste from inactive users&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How Floating Licenses Work
&lt;/h2&gt;

&lt;p&gt;Unlike node-locked licenses that bind to specific machines, floating licenses operate from a central license server:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Application starts&lt;/strong&gt; → Requests a license from the pool&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;License available&lt;/strong&gt; → Granted and marked as "in use"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Heartbeat signals&lt;/strong&gt; → Application proves it's still running&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Application closes&lt;/strong&gt; → License returns to the pool&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Crash or timeout&lt;/strong&gt; → Server automatically releases the license&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Check out the &lt;a href="https://github.com/soraco/qlm/blob/master/qlmdocs/fundamental-concepts/qlm-license-models.md" rel="noopener noreferrer"&gt;QLM license models documentation&lt;/a&gt; on GitHub for more details.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementation with Quick License Manager
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://soraco.co" rel="noopener noreferrer"&gt;Quick License Manager&lt;/a&gt; provides two deployment options for floating licenses:&lt;/p&gt;

&lt;h3&gt;
  
  
  Cloud-Based Floating Licenses
&lt;/h3&gt;

&lt;p&gt;The QLM License Server runs in the cloud, managed by Soraco. Your applications connect via HTTPS to check out licenses.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Advantages:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No server infrastructure to maintain&lt;/li&gt;
&lt;li&gt;Automatic updates and monitoring&lt;/li&gt;
&lt;li&gt;Built-in redundancy and uptime&lt;/li&gt;
&lt;li&gt;Works for distributed teams globally&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Learn more: &lt;a href="https://soraco.co/cloud-based-floating-licenses/" rel="noopener noreferrer"&gt;Cloud-Based Floating Licenses&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  On-Premise Floating Licenses
&lt;/h3&gt;

&lt;p&gt;You host the QLM License Server on your own infrastructure or your customer's network.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Advantages:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Full control over the license server&lt;/li&gt;
&lt;li&gt;Works in air-gapped environments&lt;/li&gt;
&lt;li&gt;Meets strict security requirements&lt;/li&gt;
&lt;li&gt;No external dependencies&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Documentation: &lt;a href="https://docs.soraco.co/docs/floating-licenses/on-premise-floating-licenses" rel="noopener noreferrer"&gt;On-Premise Floating Licenses&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;GitHub reference: &lt;a href="https://github.com/soraco/qlm/blob/master/qlmdocs/how-to/README.md" rel="noopener noreferrer"&gt;How-to guides&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Technical Considerations
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Heartbeat Mechanism
&lt;/h3&gt;

&lt;p&gt;The license server needs to know when an application crashes without properly releasing its license. QLM uses configurable heartbeat intervals:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Application sends periodic "still alive" signals&lt;/li&gt;
&lt;li&gt;Server expects heartbeats within the timeout window&lt;/li&gt;
&lt;li&gt;Missed heartbeats trigger automatic license release&lt;/li&gt;
&lt;li&gt;Prevents licenses being locked by crashed processes&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Network Dependency
&lt;/h3&gt;

&lt;p&gt;Floating licenses require network connectivity to the license server. Consider:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Connection failures&lt;/strong&gt; - How long should the app continue working?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Grace periods&lt;/strong&gt; - Allow brief disconnections without termination&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Offline checkout&lt;/strong&gt; - QLM supports &lt;a href="https://docs.soraco.co/docs/floating-licenses/cloud-floating-licenses/cloud-based-floating-licenses-check-out-for-offline-usage" rel="noopener noreferrer"&gt;temporary offline usage&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Hybrid Licensing Models
&lt;/h3&gt;

&lt;p&gt;You can support both floating and node-locked licenses in the same application. This lets you offer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Floating licenses&lt;/strong&gt; for enterprise customers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Node-locked licenses&lt;/strong&gt; for individual users (&lt;a href="https://github.com/soraco/qlm/blob/master/qlmdocs/how-to/how-to-use-computer-bound-keys-with-qlm-express.md" rel="noopener noreferrer"&gt;see computer-bound keys&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mixed deployments&lt;/strong&gt; within the same organization&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;See: &lt;a href="https://docs.soraco.co/docs/floating-licenses/on-premise-floating-licenses/how-to-support-floating-and-node-locked-licences-in-t" rel="noopener noreferrer"&gt;Supporting floating and node-locked licenses together&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Advanced Features
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Product Properties
&lt;/h3&gt;

&lt;p&gt;Customize license behavior using &lt;a href="https://github.com/soraco/qlm/blob/master/qlmdocs/how-to/product-properties.md" rel="noopener noreferrer"&gt;product properties&lt;/a&gt; to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set different feature sets per license&lt;/li&gt;
&lt;li&gt;Control expiry dates for specific features&lt;/li&gt;
&lt;li&gt;Define custom license attributes&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Maintenance Plans
&lt;/h3&gt;

&lt;p&gt;Implement upgrade protection with &lt;a href="https://github.com/soraco/qlm/blob/master/qlmdocs/faq/qlm-maintenance-plan.md" rel="noopener noreferrer"&gt;QLM maintenance plans&lt;/a&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Control which versions customers can upgrade to&lt;/li&gt;
&lt;li&gt;Manage perpetual licenses with optional upgrade subscriptions&lt;/li&gt;
&lt;li&gt;Validate version entitlements during activation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;View the &lt;a href="https://soraco.co/quick-license-manager/quick-license-manager-features/" rel="noopener noreferrer"&gt;complete feature list&lt;/a&gt; for all supported capabilities.&lt;/p&gt;

&lt;h2&gt;
  
  
  Comparison with Other Licensing Models
&lt;/h2&gt;

&lt;p&gt;For different use cases, consider:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Trial licenses&lt;/strong&gt; - Time-limited evaluation periods (&lt;a href="https://dev.to/olivier_moussalli_e3492f5/trial-license-implementation-patterns-in-c-a-technical-deep-dive-338l"&gt;see implementation guide&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Offline activation&lt;/strong&gt; - Air-gapped environments (&lt;a href="https://dev.to/olivier_moussalli_e3492f5/offline-license-activation-with-qr-codes-serving-air-gapped-environments-in-c-1c5k"&gt;QR code approach&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;License protection&lt;/strong&gt; - Understanding the difference from code obfuscation (&lt;a href="https://dev.to/olivier_moussalli_e3492f5/license-protection-vs-code-obfuscation-what-net-developers-actually-need-4mkg"&gt;read more&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;To implement floating licenses in your .NET application:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Choose your deployment model (cloud vs on-premise)&lt;/li&gt;
&lt;li&gt;Configure the QLM License Server&lt;/li&gt;
&lt;li&gt;Integrate the QLM SDK into your application&lt;/li&gt;
&lt;li&gt;Set heartbeat intervals and timeout policies&lt;/li&gt;
&lt;li&gt;Test license checkout, heartbeat, and release flows&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;GitHub Resources:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/soraco/qlm" rel="noopener noreferrer"&gt;QLM Documentation Repository&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/soraco/qlm/blob/master/qlmdocs/how-to/README.md" rel="noopener noreferrer"&gt;How-to Guides&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.soraco.co/docs/floating-licenses/cloud-floating-licenses/how-to-implement-cloud-based-floating-licenses" rel="noopener noreferrer"&gt;Implementation Guide&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Floating licenses make enterprise software more accessible by reducing per-seat costs while maintaining license compliance. &lt;a href="https://soraco.co" rel="noopener noreferrer"&gt;Quick License Manager&lt;/a&gt; handles the complex server infrastructure, heartbeat monitoring, and failover scenarios - letting you focus on your application features.&lt;/p&gt;

&lt;p&gt;Explore the &lt;a href="https://github.com/soraco/qlm" rel="noopener noreferrer"&gt;GitHub repository&lt;/a&gt; for detailed documentation and examples.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Need help with .NET licensing? Visit &lt;a href="https://soraco.co" rel="noopener noreferrer"&gt;soraco.co&lt;/a&gt;, check out our &lt;a href="https://github.com/soraco/qlm" rel="noopener noreferrer"&gt;GitHub repo&lt;/a&gt;, or read our other &lt;a href="https://dev.to/olivier_moussalli_e3492f5"&gt;licensing tutorials&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>csharp</category>
      <category>c</category>
    </item>
    <item>
      <title>Build vs Buy: Should You Create Your Own .NET License System?</title>
      <dc:creator>Soraco Technologies</dc:creator>
      <pubDate>Mon, 19 Jan 2026 07:11:33 +0000</pubDate>
      <link>https://forem.com/soraco-technologies/build-vs-buy-should-you-create-your-own-net-license-system-3g40</link>
      <guid>https://forem.com/soraco-technologies/build-vs-buy-should-you-create-your-own-net-license-system-3g40</guid>
      <description>&lt;p&gt;"How hard can it be to build our own license management system?"&lt;/p&gt;

&lt;p&gt;I hear this question at least once a month from .NET developers. The logic makes sense: you're already building complex software, so generating and validating license keys seems straightforward.&lt;/p&gt;

&lt;p&gt;Let me show you the real costs—both obvious and hidden—of building your own licensing system.&lt;/p&gt;

&lt;h2&gt;
  
  
  The "Simple" Requirements List
&lt;/h2&gt;

&lt;p&gt;When developers think about license management, they usually imagine:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Generate unique license keys&lt;/li&gt;
&lt;li&gt;Validate keys when the app starts&lt;/li&gt;
&lt;li&gt;Maybe track activations&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's the easy part. Here's what you're actually signing up for:&lt;/p&gt;

&lt;h3&gt;
  
  
  Technical Requirements
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;License Generation &amp;amp; Security:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Secure license key generation&lt;/li&gt;
&lt;li&gt;Key format design (readable vs. machine-only)&lt;/li&gt;
&lt;li&gt;Preventing key prediction or brute force attacks&lt;/li&gt;
&lt;li&gt;Hardware ID binding to prevent sharing&lt;/li&gt;
&lt;li&gt;Handling VM/container environments&lt;/li&gt;
&lt;li&gt;Managing key revocation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Activation &amp;amp; Validation:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Online activation server (hosting, security, uptime)&lt;/li&gt;
&lt;li&gt;Offline activation workflow&lt;/li&gt;
&lt;li&gt;Trial key management with expiration&lt;/li&gt;
&lt;li&gt;Grace periods for connectivity issues&lt;/li&gt;
&lt;li&gt;Clock tampering detection&lt;/li&gt;
&lt;li&gt;Multiple activation limits per key&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Business Logic:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Perpetual vs. subscription licenses&lt;/li&gt;
&lt;li&gt;Feature-based licensing&lt;/li&gt;
&lt;li&gt;Floating licenses for enterprise&lt;/li&gt;
&lt;li&gt;Upgrade/downgrade paths&lt;/li&gt;
&lt;li&gt;Maintenance plan tracking&lt;/li&gt;
&lt;li&gt;License transfers between machines&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Integration:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;E-commerce platform integration (Stripe, PayPal, etc.)&lt;/li&gt;
&lt;li&gt;Automated key delivery emails&lt;/li&gt;
&lt;li&gt;Subscription renewal automation&lt;/li&gt;
&lt;li&gt;Failed payment handling&lt;/li&gt;
&lt;li&gt;Refund processing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Analytics &amp;amp; Reporting:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Installation tracking&lt;/li&gt;
&lt;li&gt;Activation success rates&lt;/li&gt;
&lt;li&gt;Trial conversion metrics&lt;/li&gt;
&lt;li&gt;License usage analytics&lt;/li&gt;
&lt;li&gt;Compliance reporting for audits&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Support Infrastructure:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Customer portal for license management&lt;/li&gt;
&lt;li&gt;Self-service activation for offline users&lt;/li&gt;
&lt;li&gt;QR code generation for mobile activation&lt;/li&gt;
&lt;li&gt;License recovery system&lt;/li&gt;
&lt;li&gt;Admin dashboard for your support team&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Are you still thinking "how hard can it be?"&lt;/p&gt;

&lt;h2&gt;
  
  
  The Real Development Timeline
&lt;/h2&gt;

&lt;p&gt;Let me break down actual development time based on watching teams build licensing systems:&lt;/p&gt;

&lt;h3&gt;
  
  
  Phase 1: Core System (Weeks 1-8)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;License key algorithm and security: 2 weeks&lt;/li&gt;
&lt;li&gt;Basic validation logic: 1 week&lt;/li&gt;
&lt;li&gt;Hardware binding: 1 week&lt;/li&gt;
&lt;li&gt;Online activation server: 2 weeks&lt;/li&gt;
&lt;li&gt;Offline activation flow: 1 week&lt;/li&gt;
&lt;li&gt;Database design and setup: 1 week&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Phase 2: Business Features (Weeks 9-16)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Trial management: 1 week&lt;/li&gt;
&lt;li&gt;Subscription handling: 2 weeks&lt;/li&gt;
&lt;li&gt;Feature-based licensing: 1 week&lt;/li&gt;
&lt;li&gt;Floating licenses: 2 weeks&lt;/li&gt;
&lt;li&gt;Upgrade logic: 1 week&lt;/li&gt;
&lt;li&gt;Edge case handling: 1 week&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Phase 3: Integration &amp;amp; Admin (Weeks 17-24)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;E-commerce integration: 3 weeks&lt;/li&gt;
&lt;li&gt;Email automation: 1 week&lt;/li&gt;
&lt;li&gt;Customer portal: 2 weeks&lt;/li&gt;
&lt;li&gt;Admin dashboard: 2 weeks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Total: ~6 months&lt;/strong&gt; for a senior developer working full-time.&lt;/p&gt;

&lt;p&gt;But wait—you still need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Security auditing&lt;/li&gt;
&lt;li&gt;Testing edge cases&lt;/li&gt;
&lt;li&gt;Documentation&lt;/li&gt;
&lt;li&gt;Customer support tools&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Add another 2-3 months for a production-ready system.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Hidden Costs
&lt;/h2&gt;

&lt;p&gt;Here's where the "build it ourselves" plan really falls apart:&lt;/p&gt;

&lt;h3&gt;
  
  
  Opportunity Cost
&lt;/h3&gt;

&lt;p&gt;While you're building license management, you're NOT:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Building features your customers want&lt;/li&gt;
&lt;li&gt;Fixing bugs&lt;/li&gt;
&lt;li&gt;Marketing your actual product&lt;/li&gt;
&lt;li&gt;Closing sales&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's say your developer costs $100/hour (loaded cost). That 6-month build is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;6 months × 160 hours = 960 hours&lt;/li&gt;
&lt;li&gt;960 hours × $100 = &lt;strong&gt;$96,000&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But the opportunity cost is even higher. Those features you didn't build? They would have generated revenue and attracted customers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Maintenance &amp;amp; Security
&lt;/h3&gt;

&lt;p&gt;License systems aren't build-once-and-forget. You need ongoing:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Security updates:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Responding to vulnerabilities&lt;/li&gt;
&lt;li&gt;Updating encryption as standards evolve&lt;/li&gt;
&lt;li&gt;Handling new attack vectors&lt;/li&gt;
&lt;li&gt;Keeping up with OS changes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Platform support:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Windows updates&lt;/li&gt;
&lt;li&gt;Linux distribution changes&lt;/li&gt;
&lt;li&gt;macOS security requirements&lt;/li&gt;
&lt;li&gt;.NET framework updates&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;E-commerce changes:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Payment provider API updates&lt;/li&gt;
&lt;li&gt;New webhook formats&lt;/li&gt;
&lt;li&gt;Compliance requirements (GDPR, PCI, etc.)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Estimate 10-20 hours per month = $1,000-$2,000 monthly ongoing cost.&lt;/p&gt;

&lt;h3&gt;
  
  
  Support Burden
&lt;/h3&gt;

&lt;p&gt;When licensing breaks, customers can't use your software. These are always Priority 1 emergencies:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"My activation isn't working!"&lt;/li&gt;
&lt;li&gt;"I changed my motherboard, now it won't activate"&lt;/li&gt;
&lt;li&gt;"The trial expired but I just downloaded it"&lt;/li&gt;
&lt;li&gt;"My license key shows as already used"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You'll spend countless hours debugging activation issues instead of building features.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Alternative: Buy QLM
&lt;/h2&gt;

&lt;p&gt;Let's compare costs over 5 years:&lt;/p&gt;

&lt;h3&gt;
  
  
  5-Year Cost Comparison
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Option&lt;/th&gt;
&lt;th&gt;Year 1&lt;/th&gt;
&lt;th&gt;Years 2-5&lt;/th&gt;
&lt;th&gt;Total 5 Years&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Build Your Own&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$96,000 + lost opportunity&lt;/td&gt;
&lt;td&gt;$24,000/year maintenance&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;$192,000+&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Buy QLM Enterprise&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$999&lt;/td&gt;
&lt;td&gt;$999/year&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;$4,995&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Buy QLM Professional&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$699&lt;/td&gt;
&lt;td&gt;$699/year&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;$3,495&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;That's not including the opportunity cost of features not built, customers not acquired, and revenue not generated while you spent 6 months building infrastructure instead of product.&lt;/p&gt;

&lt;h2&gt;
  
  
  What You Get With QLM
&lt;/h2&gt;

&lt;p&gt;Instead of 6 months of development, you get immediate access to:&lt;/p&gt;

&lt;p&gt;✅ Secure license key generation&lt;br&gt;
✅ Online &amp;amp; offline activation&lt;br&gt;
✅ Trial management with automation&lt;br&gt;
✅ Subscription handling&lt;br&gt;
✅ E-commerce integration (12 platforms)&lt;br&gt;
✅ Customer portal&lt;br&gt;
✅ Admin dashboard&lt;br&gt;
✅ Analytics &amp;amp; reporting&lt;br&gt;
✅ Email automation&lt;br&gt;
✅ Floating licenses (Enterprise)&lt;br&gt;
✅ Cross-platform support (Enterprise)&lt;br&gt;
✅ Support from people who do this full-time&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Implementation time:&lt;/strong&gt; Most developers have it running in &amp;lt; 1 day.&lt;/p&gt;

&lt;h2&gt;
  
  
  When Building Makes Sense
&lt;/h2&gt;

&lt;p&gt;There ARE valid reasons to build your own:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Unique requirements:&lt;/strong&gt; Your licensing model is so unusual that no commercial solution fits&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Extreme scale:&lt;/strong&gt; You have millions of activations per day (most devs don't)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Complete control:&lt;/strong&gt; You need to modify core algorithms frequently&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Learning exercise:&lt;/strong&gt; You're building it to understand how licensing works (but don't use it in production)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For 95% of developers, these don't apply.&lt;/p&gt;

&lt;h2&gt;
  
  
  The "We'll Start Simple" Trap
&lt;/h2&gt;

&lt;p&gt;I've seen this pattern dozens of times:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Month 1:&lt;/strong&gt; "We'll just generate simple keys"&lt;br&gt;
&lt;strong&gt;Month 3:&lt;/strong&gt; "Now we need activation tracking"&lt;br&gt;
&lt;strong&gt;Month 6:&lt;/strong&gt; "Customers want trial periods"&lt;br&gt;
&lt;strong&gt;Month 9:&lt;/strong&gt; "We need to integrate with Stripe"&lt;br&gt;
&lt;strong&gt;Month 12:&lt;/strong&gt; "Why is this so complex?"&lt;br&gt;
&lt;strong&gt;Month 18:&lt;/strong&gt; "Let's just buy QLM"&lt;/p&gt;

&lt;p&gt;Now you've spent 18 months AND you still need to migrate to a proper system.&lt;/p&gt;

&lt;p&gt;Start with the right foundation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Decision Framework
&lt;/h2&gt;

&lt;p&gt;Ask yourself:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is license management your core competency?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No? Buy it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Is it a competitive advantage?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No? Buy it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Will it directly generate revenue?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Not by itself? Buy it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Do you have 6+ months for infrastructure instead of features?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No? Buy it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Can you maintain it long-term with security updates?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No? Buy it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;See a pattern?&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started With QLM
&lt;/h2&gt;

&lt;p&gt;Ready to implement licensing the smart way?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Start Free&lt;/strong&gt;: Download a &lt;a href="https://soraco.co/downloads/qlmdownloadtrial" rel="noopener noreferrer"&gt;30-day trial&lt;/a&gt; with full functionality&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Quick Implementation&lt;/strong&gt;: Follow the &lt;a href="https://soraco.co/courses/qlm-tutorials/" rel="noopener noreferrer"&gt;step-by-step tutorials&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Choose Your Edition&lt;/strong&gt;: &lt;a href="https://soraco.co/pricing/" rel="noopener noreferrer"&gt;Compare pricing&lt;/a&gt; for Express, Professional, and Enterprise&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Works with .NET 6, 7, 8, 9, and 10. Most developers have basic validation running same day.&lt;/p&gt;

&lt;p&gt;For complete implementation details, check the &lt;a href="https://docs.soraco.co" rel="noopener noreferrer"&gt;QLM documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Bottom Line
&lt;/h2&gt;

&lt;p&gt;Building your own license management system costs &lt;strong&gt;$192,000+&lt;/strong&gt; over 5 years in development and maintenance.&lt;/p&gt;

&lt;p&gt;Buying QLM costs &lt;strong&gt;$3,495-$4,995&lt;/strong&gt; over 5 years and you start generating revenue immediately.&lt;/p&gt;

&lt;p&gt;The math is pretty clear.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Focus on building your product, not infrastructure. &lt;a href="https://soraco.co" rel="noopener noreferrer"&gt;Quick License Manager&lt;/a&gt; handles license validation, trial management, and subscription automation so you can ship features instead of building license servers.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>csharp</category>
      <category>licensing</category>
      <category>architecture</category>
    </item>
    <item>
      <title>License Protection vs. Code Obfuscation: What .NET Developers Actually Need</title>
      <dc:creator>Soraco Technologies</dc:creator>
      <pubDate>Mon, 19 Jan 2026 06:01:50 +0000</pubDate>
      <link>https://forem.com/soraco-technologies/license-protection-vs-code-obfuscation-what-net-developers-actually-need-4mkg</link>
      <guid>https://forem.com/soraco-technologies/license-protection-vs-code-obfuscation-what-net-developers-actually-need-4mkg</guid>
      <description>&lt;p&gt;If you're building commercial .NET software, you've probably heard about both code obfuscation and license protection. But what's the actual difference? And which one do you need?&lt;/p&gt;

&lt;p&gt;Let me break it down in plain English.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's the Difference?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Code Obfuscation&lt;/strong&gt; makes your code harder to reverse-engineer by scrambling variable names, removing metadata, and transforming logic. Think of it like putting a complex lock on your front door.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;License Protection&lt;/strong&gt; controls who can actually use your software by validating license keys. It's like having a security guard check IDs at the entrance.&lt;/p&gt;

&lt;p&gt;Here's the thing: they solve different problems.&lt;/p&gt;

&lt;h2&gt;
  
  
  When You Need Each One
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Use Code Obfuscation When:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;You have proprietary algorithms you want to protect&lt;/li&gt;
&lt;li&gt;Your app contains sensitive business logic&lt;/li&gt;
&lt;li&gt;You're worried about competitors copying your code&lt;/li&gt;
&lt;li&gt;You work in industries with IP concerns (finance, healthcare, etc.)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Use License Protection When:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;You sell software commercially&lt;/li&gt;
&lt;li&gt;You want to offer trial periods&lt;/li&gt;
&lt;li&gt;You need to prevent unauthorized sharing&lt;/li&gt;
&lt;li&gt;You want to enforce subscription renewals&lt;/li&gt;
&lt;li&gt;You need to track installations and usage&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Real Talk: Should You Do Both?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;For B2C products (especially those prone to being cracked): YES, use both.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Obfuscation protects your intellectual property. License protection controls who can use it. Together, they create a much stronger defense.&lt;/p&gt;

&lt;p&gt;For B2B enterprise software where you have direct customer relationships and less piracy risk, license protection alone might be sufficient.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cost Comparison
&lt;/h2&gt;

&lt;p&gt;Let's be honest about pricing:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code Obfuscation:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ConfuserEx: Free (open source)&lt;/li&gt;
&lt;li&gt;Dotfuscator Professional: $1,999+&lt;/li&gt;
&lt;li&gt;.NET Reactor: €179&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;License Protection:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;QLM is available in three editions with royalty-free distribution to your end users:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;QLM Express&lt;/strong&gt; ($200/year): Essential license management for solo developers and small projects&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;QLM Professional&lt;/strong&gt; ($699/year): Adds analytics, automation, and e-commerce integration for growing teams&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;QLM Enterprise&lt;/strong&gt; ($999/year): Full feature set including cross-platform support, floating licenses, and advanced analytics&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;All prices are per developer/administrator license&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Real-World Example: The "Build Once, Sell Many" Scenario
&lt;/h2&gt;

&lt;p&gt;Let's say you're building a desktop app for small businesses. Here's what each approach gives you:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;With Obfuscation Only:&lt;/strong&gt;&lt;br&gt;
Anyone with a valid license can reverse-engineer your code. Once cracked, they can distribute it freely. You have no way to track who's using it or enforce trials.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;With License Protection Only:&lt;/strong&gt;&lt;br&gt;
You control who can use your software and for how long. You can offer 30-day trials, track conversions, and prevent casual sharing. But your code is still readable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;With Both:&lt;/strong&gt;&lt;br&gt;
Your code is protected AND you control access. Someone would need to both crack your obfuscation AND bypass your license validation. Much harder.&lt;/p&gt;
&lt;h2&gt;
  
  
  Quick Implementation Example
&lt;/h2&gt;

&lt;p&gt;Here's how simple license protection can be with QLM:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;QlmLicenseLib&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LicenseValidator&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;QlmLicense&lt;/span&gt; &lt;span class="n"&gt;license&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;ValidateLicense&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;activationKey&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;license&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;QlmLicense&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;license&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;DefineProduct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"MyApp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;isValid&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;license&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ValidateLicenseAtStartup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;activationKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
            &lt;span class="k"&gt;out&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;isValid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Show activation dialog&lt;/span&gt;
            &lt;span class="nf"&gt;ShowActivationDialog&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can add obfuscation to this code during your build process.&lt;/p&gt;

&lt;h2&gt;
  
  
  My Recommendation
&lt;/h2&gt;

&lt;p&gt;Start with license protection. It solves the immediate business problem: controlling who can use your software and for how long.&lt;/p&gt;

&lt;p&gt;Then, if you're seeing piracy issues or have valuable IP to protect, add obfuscation to your build pipeline.&lt;/p&gt;

&lt;p&gt;For B2C products that are likely targets for cracking (games, creative tools, consumer utilities), implement both from the start.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;Want to add license protection to your .NET app?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Download QLM Trial&lt;/strong&gt;: Get a &lt;a href="https://soraco.co/downloads/qlmdownloadtrial" rel="noopener noreferrer"&gt;30-day trial&lt;/a&gt; with full functionality&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Follow the Quick Start&lt;/strong&gt;: Check out the &lt;a href="https://soraco.co/courses/qlm-tutorials/" rel="noopener noreferrer"&gt;QLM tutorials&lt;/a&gt; for step-by-step guidance&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Implement in &amp;lt; 1 Day&lt;/strong&gt;: Most developers have basic license validation running same day&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For more details on implementation, see the &lt;a href="https://docs.soraco.co" rel="noopener noreferrer"&gt;QLM documentation&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Building commercial .NET software? &lt;a href="https://soraco.co" rel="noopener noreferrer"&gt;Quick License Manager&lt;/a&gt; handles license validation, trial management, and subscription automation so you can focus on your product.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>csharp</category>
      <category>security</category>
      <category>licensing</category>
    </item>
    <item>
      <title>5 Reasons Why Your .NET App Needs License Protection (Even If You're Just Starting Out)</title>
      <dc:creator>Soraco Technologies</dc:creator>
      <pubDate>Mon, 19 Jan 2026 05:46:17 +0000</pubDate>
      <link>https://forem.com/soraco-technologies/5-reasons-why-your-net-app-needs-license-protection-even-if-youre-just-starting-out-3p73</link>
      <guid>https://forem.com/soraco-technologies/5-reasons-why-your-net-app-needs-license-protection-even-if-youre-just-starting-out-3p73</guid>
      <description>&lt;p&gt;When you're launching a new .NET app, license protection might feel like something you can "add later." But here's what I've learned from watching developers build commercial software: waiting costs you money and customers.&lt;/p&gt;

&lt;p&gt;Let me show you why license protection should be on your Day 1 checklist.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. You're Leaving Money on the Table
&lt;/h2&gt;

&lt;p&gt;Without license protection, there's nothing stopping a single customer from:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Installing your app on 50 computers&lt;/li&gt;
&lt;li&gt;Sharing it with their entire company&lt;/li&gt;
&lt;li&gt;Posting the installer on internal forums&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One sale. Fifty users.&lt;/p&gt;

&lt;p&gt;I've seen this happen with a project management tool. A single $299 license was being used by 120 people across three offices. That's over $35,000 in lost revenue.&lt;/p&gt;

&lt;p&gt;With license protection, that same company would need to either buy 120 licenses or stay within their licensed user count. That's the difference between a $299 customer and a $35,000+ enterprise account.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real numbers:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Average unauthorized sharing: 4-8 installations per license&lt;/li&gt;
&lt;li&gt;Typical revenue recovery with licensing: 30-60% of lost sales&lt;/li&gt;
&lt;li&gt;Break-even timeline: Usually within first month&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2. Professional Credibility
&lt;/h2&gt;

&lt;p&gt;Here's an uncomfortable truth: when customers can't activate your software, they assume it's either:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Not a real business product&lt;/li&gt;
&lt;li&gt;Still in beta&lt;/li&gt;
&lt;li&gt;Soon to be abandoned&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your app might be amazing, but without a proper licensing system, you're signaling "hobby project" instead of "professional software."&lt;/p&gt;

&lt;p&gt;I've watched developers lose enterprise deals specifically because they couldn't demonstrate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;License management capabilities&lt;/li&gt;
&lt;li&gt;Trial-to-paid conversion workflow&lt;/li&gt;
&lt;li&gt;Compliance reporting for IT departments&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Enterprise buyers need to show their procurement team a legitimate software licensing process. No license system = no enterprise sales.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Automated Trials Save You Hours Every Week
&lt;/h2&gt;

&lt;p&gt;Before license protection: Every trial request means manually emailing an installer, following up when it expires, tracking who converted, and reminding users about expiration.&lt;/p&gt;

&lt;p&gt;After license protection: Users get instant trial keys, automatic expiration, and conversion tracking. Zero manual work.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Time saved per week (typical):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No more manual trial key emails: ~3 hours&lt;/li&gt;
&lt;li&gt;No more trial extension requests: ~2 hours
&lt;/li&gt;
&lt;li&gt;No more "did they convert?" detective work: ~1 hour&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's 6 hours weekly to actually build features instead of managing trials.&lt;/p&gt;

&lt;p&gt;With QLM, your trial workflow is completely automated. Users enter their email, receive a 30-day trial key instantly, and get automated reminders as expiration approaches. You get analytics on who's actually using the trial.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Version Control Made Simple
&lt;/h2&gt;

&lt;p&gt;Shipping a new version? Without license protection, you can't control who upgrades.&lt;/p&gt;

&lt;p&gt;This creates nightmare scenarios:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Legacy customers on v1.0 demanding support for bugs fixed 3 versions ago&lt;/li&gt;
&lt;li&gt;Users mixing incompatible versions across their team&lt;/li&gt;
&lt;li&gt;No way to sunset old versions for security updates&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With license protection, you can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automatically deny activation for old versions after a cutoff date&lt;/li&gt;
&lt;li&gt;Offer upgrade paths tied to maintenance plans&lt;/li&gt;
&lt;li&gt;Force security updates for critical vulnerabilities&lt;/li&gt;
&lt;li&gt;Track exactly which versions are in use&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Real example:&lt;/strong&gt; A security firm discovered a critical vulnerability in their .NET app. With license validation, they blocked activation for vulnerable versions and required an update. Without it, they would have had exposed installations running indefinitely.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Know Your Users
&lt;/h2&gt;

&lt;p&gt;You're building features in the dark if you don't know:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How many active installations you have&lt;/li&gt;
&lt;li&gt;Which features get used&lt;/li&gt;
&lt;li&gt;When trials convert (or don't)&lt;/li&gt;
&lt;li&gt;Installation vs. activation rates&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;License protection gives you this data automatically.&lt;/p&gt;

&lt;p&gt;QLM's analytics track:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Daily active users and usage patterns&lt;/li&gt;
&lt;li&gt;Trial-to-paid conversion rates&lt;/li&gt;
&lt;li&gt;Feature adoption metrics&lt;/li&gt;
&lt;li&gt;Installation and uninstallation events&lt;/li&gt;
&lt;li&gt;Geographic distribution of your user base&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This isn't surveillance—it's business intelligence. You'll know if your trial length is too short, if users are churning after 60 days, or if nobody's using that feature you spent 3 months building.&lt;/p&gt;

&lt;h2&gt;
  
  
  "But I'm Just Starting Out..."
&lt;/h2&gt;

&lt;p&gt;I hear this a lot. "We'll add licensing once we have customers."&lt;/p&gt;

&lt;p&gt;Here's why that's backwards:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Adding licensing later means:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Refactoring your entire startup sequence&lt;/li&gt;
&lt;li&gt;Breaking existing installations&lt;/li&gt;
&lt;li&gt;Dealing with angry "it was free before!" users&lt;/li&gt;
&lt;li&gt;Losing weeks to implementation instead of features&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Adding licensing on Day 1 means:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Trial users expect activation (no surprise)&lt;/li&gt;
&lt;li&gt;You have revenue data from the start&lt;/li&gt;
&lt;li&gt;Enterprise customers take you seriously immediately&lt;/li&gt;
&lt;li&gt;Implementation is simpler (no legacy users to migrate)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Quick Start: Add License Protection in &amp;lt; 1 Day
&lt;/h2&gt;

&lt;p&gt;Here's the actual implementation for .NET:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;QlmLicenseLib&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AppStartup&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;InitializeLicense&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;license&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;QlmLicense&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;license&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;DefineProduct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"MyApp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;isValid&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;license&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ValidateLicenseAtStartup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;activationKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="k"&gt;out&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;isValid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;ShowActivationDialog&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. Add this to your startup code, configure your product details, and you're protected.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Bottom Line
&lt;/h2&gt;

&lt;p&gt;License protection isn't about being aggressive or assuming your users are thieves. It's about:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Capturing revenue&lt;/strong&gt; you're already earning (but not collecting)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Looking professional&lt;/strong&gt; to enterprise buyers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Saving time&lt;/strong&gt; on manual trial management&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Controlling updates&lt;/strong&gt; for security and support&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Understanding users&lt;/strong&gt; to build better features&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Even if you're a solo developer launching your first commercial app, these benefits pay for themselves immediately.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ready to Implement?
&lt;/h2&gt;

&lt;p&gt;QLM works with .NET 6, 7, 8, 9, and 10. Most developers have it running in less than a day.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Get Started&lt;/strong&gt;: Download a &lt;a href="https://soraco.co/downloads/qlmdownloadtrial" rel="noopener noreferrer"&gt;30-day trial&lt;/a&gt; with full functionality&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Learn the Basics&lt;/strong&gt;: Follow the &lt;a href="https://soraco.co/courses/qlm-tutorials/" rel="noopener noreferrer"&gt;step-by-step tutorials&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Go Live&lt;/strong&gt;: &lt;a href="https://soraco.co/pricing/" rel="noopener noreferrer"&gt;Pricing starts at $200/year&lt;/a&gt; for QLM Express&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For complete implementation details, check the &lt;a href="https://docs.soraco.co" rel="noopener noreferrer"&gt;QLM documentation&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Building commercial .NET software? &lt;a href="https://soraco.co" rel="noopener noreferrer"&gt;Quick License Manager&lt;/a&gt; handles license validation, trial automation, and analytics so you can focus on your product instead of infrastructure.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>csharp</category>
      <category>licensing</category>
      <category>business</category>
    </item>
  </channel>
</rss>
