Your customer's laptop just died. Hard drive failure. Motherboard fried. Computer won't boot. They call support: "I need my license on my new computer."
If your licensing system can't handle this scenario gracefully, you've got an angry customer, a support ticket nightmare, and potentially a lost renewal. This article shows you how to implement robust license transfer and deactivation that works even when computers are dead.
The Dead Computer Problem
Common scenarios that require license transfer:
- Hardware failure - Computer won't boot
- Hardware upgrade - New motherboard, new hard drive
- Computer replacement - Old laptop → new laptop
- OS reinstall - Fresh Windows installation
- Theft or loss - Computer is gone
- Corporate refresh - IT replaces all workstations
Industry data:
- 40% of enterprise customers transfer licenses at least once per year
- Hardware failure accounts for 60% of transfer requests
- Average support ticket cost: $25-50 per incident
- Average resolution time without automation: 2-4 hours
If you don't automate license transfers, you're spending thousands on support tickets.
License Deactivation Methods
Quick License Manager supports multiple deactivation approaches depending on the computer's status:
1. Online Deactivation (Computer is Functional)
When to use:
- Computer is working normally
- User has internet connection
- Planned hardware upgrade
- Voluntary license transfer
How it works:
- User clicks "Deactivate" in your application
- Application connects to license server
- Server releases the license
- Local keys are deleted
- License can be activated on new computer
2. Offline Deactivation (Computer is Functional, No Internet)
When to use:
- Computer works but no internet connection
- Air-gapped environments
- Secure facilities
How it works:
- Application generates Deactivation Verification Code (DVC)
- User accesses self-service portal from another device
- User enters activation key + DVC
- Server releases license
- User can activate on new computer
3. Dead Computer Deactivation (Computer is Not Functional)
When to use:
- Hardware failure
- Computer won't boot
- Lost or stolen computer
- Computer is physically destroyed
How it works:
- User contacts support OR uses self-service portal
- Vendor deactivates license from management console
- License immediately available for new activation
More info: How customers deactivate licenses
Implementing Online Deactivation
Step 1: Basic Deactivation
using QLM.LicenseLib;
public class LicenseDeactivationManager
{
private LicenseValidator lv;
public LicenseDeactivationManager(string settingsFile)
{
lv = new LicenseValidator(settingsFile);
}
public bool DeactivateLicense()
{
try
{
string response;
// Release license from server
bool success = lv.QlmLicenseObject.ReleaseLicense(
webServiceUrl: lv.QlmLicenseObject.DefaultWebServiceUrl,
activationKey: lv.ActivationKey,
computerID: lv.QlmLicenseObject.GetComputerID(),
response: out response
);
if (success)
{
// Delete local keys
lv.QlmLicenseObject.DeleteKeys();
MessageBox.Show(
"License deactivated successfully!\n\n" +
"You can now activate it on another computer.",
"Deactivation Complete",
MessageBoxButtons.OK,
MessageBoxIcon.Information
);
return true;
}
else
{
MessageBox.Show(
$"Deactivation failed: {response}",
"Error",
MessageBoxButtons.OK,
MessageBoxIcon.Error
);
return false;
}
}
catch (Exception ex)
{
MessageBox.Show(
$"Deactivation error: {ex.Message}",
"Error",
MessageBoxButtons.OK,
MessageBoxIcon.Error
);
return false;
}
}
}
Step 2: Deactivation with User Confirmation
public class SafeDeactivation
{
public void ShowDeactivationDialog()
{
DialogResult result = MessageBox.Show(
"Are you sure you want to deactivate this license?\n\n" +
"After deactivation, you will need to reactivate to use this software.\n\n" +
"You can activate on another computer after deactivating.",
"Confirm Deactivation",
MessageBoxButtons.YesNo,
MessageBoxIcon.Question
);
if (result == DialogResult.Yes)
{
bool success = PerformDeactivation();
if (success)
{
// Close application after deactivation
Application.Exit();
}
}
}
private bool PerformDeactivation()
{
var deactivator = new LicenseDeactivationManager("settings.xml");
return deactivator.DeactivateLicense();
}
}
Step 3: Deactivation During Uninstall
// In your installer (WiX custom action)
public class UninstallActions
{
[CustomAction]
public static ActionResult DeactivateOnUninstall(Session session)
{
try
{
// Check if user wants to deactivate
DialogResult result = MessageBox.Show(
"Do you want to deactivate your license?\n\n" +
"Choose 'Yes' if you plan to install on another computer.\n" +
"Choose 'No' if you're reinstalling on this same computer.",
"License Deactivation",
MessageBoxButtons.YesNoCancel,
MessageBoxIcon.Question
);
if (result == DialogResult.Yes)
{
var deactivator = new LicenseDeactivationManager("settings.xml");
deactivator.DeactivateLicense();
}
return ActionResult.Success;
}
catch
{
// Don't fail uninstall if deactivation fails
return ActionResult.Success;
}
}
}
Learn more: Clearing license keys from end-user systems
Implementing Offline Deactivation
Understanding Deactivation Verification Codes (DVC)
The problem: When a computer is offline, we can't verify with the server that the user actually deactivated the license. Users could claim to deactivate but keep using the software.
The solution: Generate a unique Deactivation Verification Code (DVC) that proves the user deactivated on their offline computer.
The workflow:
- User clicks "Deactivate" in offline application
- Application generates DVC based on activation key + computer ID
- User goes to self-service portal on a device with internet
- User enters activation key + DVC on portal
- Server validates DVC and releases license
- License available for new activation
More details: Deactivation Verification Code documentation
Step 1: Generate Deactivation Verification Code
public class OfflineDeactivationManager
{
private LicenseValidator lv;
public OfflineDeactivationManager(string settingsFile)
{
lv = new LicenseValidator(settingsFile);
}
public string GenerateDeactivationCode()
{
string activationKey = lv.ActivationKey;
string computerID = lv.QlmLicenseObject.GetComputerID();
// Generate deactivation verification code
string dvc = lv.QlmLicenseObject.CreateDeactivationCode(
activationKey: activationKey,
computerID: computerID,
licenseBinding: ELicenseBinding.ComputerName
);
return dvc;
}
public void ShowOfflineDeactivationInstructions()
{
string dvc = GenerateDeactivationCode();
string activationKey = lv.ActivationKey;
string instructions =
"OFFLINE DEACTIVATION INSTRUCTIONS:\n\n" +
$"1. Deactivation Verification Code:\n {dvc}\n\n" +
$"2. Activation Key:\n {activationKey}\n\n" +
"3. On a computer with internet, visit:\n" +
" https://yoursite.com/qlmselfhelp/\n\n" +
"4. Click 'Release License'\n\n" +
"5. Enter your Activation Key and Verification Code\n\n" +
"6. Click 'Deactivate'\n\n" +
"7. Your license will be released and available for activation\n on another computer";
MessageBox.Show(
instructions,
"Offline Deactivation",
MessageBoxButtons.OK,
MessageBoxIcon.Information
);
}
}
Step 2: Offline Deactivation with QR Code
using QRCoder; // NuGet: QRCoder
public class QRCodeOfflineDeactivation
{
public void ShowQRCodeDeactivation()
{
var offlineManager = new OfflineDeactivationManager("settings.xml");
string dvc = offlineManager.GenerateDeactivationCode();
string activationKey = offlineManager.GetActivationKey();
// Build deactivation URL
string deactivationUrl = BuildDeactivationUrl(
"https://yoursite.com/qlmselfhelp/",
activationKey,
dvc
);
// Generate QR code
Bitmap qrCodeImage = GenerateQRCode(deactivationUrl);
// Show QR code dialog
var dialog = new QRCodeDeactivationDialog(qrCodeImage, dvc);
dialog.ShowDialog();
}
private string BuildDeactivationUrl(
string baseUrl,
string activationKey,
string dvc)
{
var uri = new UriBuilder(baseUrl);
uri.Path += "QlmReleaseLicense.aspx";
var query = HttpUtility.ParseQueryString(uri.Query);
query["is_avkey"] = activationKey;
query["is_dvc"] = dvc;
uri.Query = query.ToString();
return uri.ToString();
}
private Bitmap GenerateQRCode(string url)
{
var qrGenerator = new QRCodeGenerator();
var qrCodeData = qrGenerator.CreateQrCode(
url,
QRCodeGenerator.ECCLevel.M
);
var qrCode = new QRCode(qrCodeData);
return qrCode.GetGraphic(20);
}
}
public class QRCodeDeactivationDialog : Form
{
private PictureBox pictureBoxQR;
private Label lblInstructions;
private Button btnDone;
public QRCodeDeactivationDialog(Bitmap qrCodeImage, string dvc)
{
InitializeComponent();
lblInstructions.Text =
"STEP 1: Scan this QR code with your smartphone\n" +
"STEP 2: Your phone will open the deactivation page\n" +
"STEP 3: Click 'Deactivate' on the page\n" +
"STEP 4: Your license will be released\n\n" +
$"Verification Code: {dvc}";
pictureBoxQR.Image = qrCodeImage;
pictureBoxQR.SizeMode = PictureBoxSizeMode.Zoom;
}
private void btnDone_Click(object sender, EventArgs e)
{
// Delete local keys
var lv = new LicenseValidator("settings.xml");
lv.QlmLicenseObject.DeleteKeys();
MessageBox.Show(
"License deactivated!\n\n" +
"You can now activate on another computer.",
"Success"
);
Application.Exit();
}
}
Learn more: Offline deactivation with QR codes
Handling Dead Computers
The Challenge
When a customer's computer is dead (won't boot, hardware failure, lost/stolen), they can't generate a Deactivation Verification Code. How do you transfer their license without letting users cheat the system?
Solution 1: Manual Deactivation by Vendor
// From QLM Management Console or API
public class VendorDeactivation
{
public bool DeactivateDeadComputer(
string activationKey,
string computerID)
{
var lv = new LicenseValidator("settings.xml");
string response;
// Vendor deactivates on behalf of customer
bool success = lv.QlmLicenseObject.ReleaseLicense(
webServiceUrl: lv.QlmLicenseObject.DefaultWebServiceUrl,
activationKey: activationKey,
computerID: computerID,
response: out response
);
if (success)
{
Console.WriteLine($"License {activationKey} deactivated from {computerID}");
// Log the deactivation
LogDeactivation(activationKey, computerID, "Dead computer - vendor override");
return true;
}
return false;
}
private void LogDeactivation(
string activationKey,
string computerID,
string reason)
{
// Record in audit trail
// Useful for detecting abuse patterns
}
}
Solution 2: Self-Service Without Verification Code
Option: Disable DVC requirement and let customers deactivate from portal without verification.
Trade-off:
- ✅ Better customer experience
- ✅ No support tickets for dead computers
- ❌ Users could abuse by claiming dead computer
- ❌ Need anti-abuse mechanisms
// Server configuration
// Set server property: customerSite/showDeactivationVerificationCode = false
When to use:
- Low-value software (<$100)
- Enterprise customers (trusted)
- Software with built-in anti-piracy checks
When NOT to use:
- High-value software (>$500)
- Consumer market with piracy concerns
Learn more: Deactivating licenses for dead computers
Anti-Abuse Mechanisms
1. Detect Illegal Computers
public class AntiAbuseValidator
{
public bool DetectIllegalComputer()
{
var lv = new LicenseValidator("settings.xml");
// Check if this computer is "illegal"
// (license valid locally but activated elsewhere on server)
bool isIllegal = lv.QlmLicenseObject.IsIllegalComputer(
webServiceUrl: lv.QlmLicenseObject.DefaultWebServiceUrl,
activationKey: lv.ActivationKey,
computerKey: lv.ComputerKey
);
if (isIllegal)
{
// User claimed computer was dead but it's still running
MessageBox.Show(
"This license is no longer valid on this computer.\n\n" +
"It has been activated on another system.",
"License Invalid",
MessageBoxButtons.OK,
MessageBoxIcon.Warning
);
// Delete local keys
lv.QlmLicenseObject.DeleteKeys();
return true;
}
return false;
}
public void ValidateWithAntiAbuse()
{
var lv = new LicenseValidator("settings.xml");
// Enable automatic illegal computer detection
lv.QlmLicenseObject.ValidateOnServer = true;
bool needsActivation = false;
string errorMsg = string.Empty;
// This automatically calls IsIllegalComputer
bool isValid = lv.ValidateLicenseAtStartup(
ELicenseBinding.ComputerName,
ref needsActivation,
ref errorMsg
);
}
}
More info: Preventing offline activation abuse
2. Limit Deactivation Frequency
public class DeactivationLimits
{
private const int MaxDeactivationsPerMonth = 3;
public bool CanDeactivate(string activationKey)
{
var lv = new LicenseValidator("settings.xml");
// Get deactivation history from server
int deactivationCount = GetRecentDeactivationCount(
activationKey,
days: 30
);
if (deactivationCount >= MaxDeactivationsPerMonth)
{
MessageBox.Show(
$"You have exceeded the maximum deactivations ({MaxDeactivationsPerMonth}) " +
"for this license in the past 30 days.\n\n" +
"Please contact support for assistance.",
"Deactivation Limit Reached",
MessageBoxButtons.OK,
MessageBoxIcon.Warning
);
return false;
}
return true;
}
private int GetRecentDeactivationCount(string activationKey, int days)
{
// Query QLM database for deactivation history
// This requires QLM API call to server
return 0; // Placeholder
}
}
3. Grace Period for Dead Computers
public class GracePeriodManager
{
private const int GracePeriodDays = 7;
public bool IsGracePeriodActive(string activationKey)
{
// Check if license was recently deactivated
DateTime lastDeactivation = GetLastDeactivationDate(activationKey);
TimeSpan timeSinceDeactivation = DateTime.Now - lastDeactivation;
if (timeSinceDeactivation.TotalDays < GracePeriodDays)
{
MessageBox.Show(
$"This license was deactivated {timeSinceDeactivation.Days} days ago.\n\n" +
$"Grace period: {GracePeriodDays} days\n" +
$"Remaining: {GracePeriodDays - timeSinceDeactivation.Days} days\n\n" +
"The software will continue to work during the grace period.",
"Grace Period Active",
MessageBoxButtons.OK,
MessageBoxIcon.Information
);
return true;
}
return false;
}
}
Using QLM License Wizard for Deactivation
The easiest approach: use QLM's built-in License Wizard with deactivation support.
public class LicenseWizardDeactivation
{
public void ShowDeactivationWizard()
{
string wizardPath = Path.Combine(
Application.StartupPath,
"QlmLicenseWizard.exe"
);
var startInfo = new ProcessStartInfo
{
FileName = wizardPath,
Arguments = BuildWizardArguments(),
UseShellExecute = false
};
Process.Start(startInfo);
}
private string BuildWizardArguments()
{
var args = new StringBuilder();
args.Append($"/settings \"{settingsFilePath}\" ");
// Show deactivation option
args.Append("/showdeactivation ");
// Enable offline deactivation
args.Append("/offlinedeactivation ");
// Enable QR code deactivation
args.Append("/qrcodedeactivation ");
return args.ToString();
}
}
The QLM License Wizard automatically:
- Detects if computer is online/offline
- Generates Deactivation Verification Code if offline
- Displays QR code for smartphone scanning
- Deletes local keys after deactivation
- Provides clear user instructions
Self-Service Portal Configuration
QLM provides a self-service portal for customer-initiated deactivations:
Portal features:
- License activation (online/offline)
- License deactivation with DVC
- License information lookup
- Trial registration
Configuration:
<!-- web.config for QlmCustomerSite -->
<appSettings>
<!-- Enable deactivation verification code -->
<add key="showDeactivationVerificationCode" value="true" />
<!-- QLM License Server URL -->
<add key="QlmLicenseServerUrl" value="https://yoursite.com/qlmLicenseServer/" />
<!-- Communication encryption key -->
<add key="CommunicationEncryptionKey" value="your-key-here" />
</appSettings>
Portal URL examples:
Activation:
https://yoursite.com/qlmselfhelp/QlmWebActivation.aspx
Deactivation:
https://yoursite.com/qlmselfhelp/QlmReleaseLicense.aspx
With pre-filled data:
https://yoursite.com/qlmselfhelp/QlmReleaseLicense.aspx?is_avkey=AXYZ-12345&is_dvc=DVC123
More info: QLM Self-Service Portal
Best Practices
1. Always Provide Multiple Deactivation Methods
Offer users choices based on their situation:
- Online deactivation (preferred)
- Offline deactivation with QR code
- Offline deactivation with manual verification code
- Support-assisted deactivation for dead computers
2. Make Deactivation Easy During Uninstall
// Prompt during uninstall
public void UninstallPrompt()
{
DialogResult result = MessageBox.Show(
"Are you:\n\n" +
"• Reinstalling on THIS computer? → Choose NO\n" +
"• Moving to ANOTHER computer? → Choose YES\n\n" +
"Deactivate your license now?",
"License Transfer",
MessageBoxButtons.YesNo,
MessageBoxIcon.Question
);
}
3. Log All Deactivations
public void LogDeactivation(
string activationKey,
string computerID,
string reason,
string userAgent)
{
// Store in QLM database for audit trail
// Helps detect abuse patterns
// Useful for support investigations
}
4. Communicate Clearly
Good deactivation message:
"License deactivated successfully! You can now activate it on another computer. Your activation key is: AXYZ-12345"
Bad deactivation message:
"Deactivation complete."
5. Test Dead Computer Scenarios
[TestClass]
public class DeactivationTests
{
[TestMethod]
public void TestOnlineDeactivation()
{
var deactivator = new LicenseDeactivationManager("test-settings.xml");
bool success = deactivator.DeactivateLicense();
Assert.IsTrue(success);
}
[TestMethod]
public void TestOfflineDeactivationCode()
{
var offlineManager = new OfflineDeactivationManager("test-settings.xml");
string dvc = offlineManager.GenerateDeactivationCode();
Assert.IsNotNull(dvc);
Assert.IsTrue(dvc.Length > 0);
}
[TestMethod]
public void TestDeadComputerDeactivation()
{
var vendorDeactivator = new VendorDeactivation();
bool success = vendorDeactivator.DeactivateDeadComputer(
"TEST-KEY",
"DEAD-COMPUTER-ID"
);
Assert.IsTrue(success);
}
}
Using Quick License Manager
Quick License Manager provides complete deactivation capabilities:
✅ Online deactivation - automatic server release
✅ Offline deactivation - with verification codes
✅ QR code deactivation - smartphone scanning
✅ Dead computer handling - vendor override
✅ Self-service portal - customer-initiated transfers
✅ Anti-abuse detection - illegal computer checks
✅ Deactivation audit trail - track all transfers
✅ QLM License Wizard - built-in deactivation UI
Download QLM and test license transfer scenarios in your environment.
Conclusion
License transfer and deactivation isn't optional—it's a critical part of the customer experience. The three scenarios require different approaches:
Functional Computer (Online):
- One-click deactivation
- Immediate server release
- 30-second process
Functional Computer (Offline):
- Deactivation Verification Code
- QR code or manual portal entry
- 2-minute process
Dead Computer:
- Support-assisted OR self-service without verification
- Balance convenience vs abuse prevention
- 5-minute process (with support)
Companies that automate license transfers reduce support tickets by 70-80% and improve customer satisfaction scores by 40-50%.
The key is making it easy for legitimate customers while having safety mechanisms to prevent abuse.
With Quick License Manager, you get comprehensive deactivation capabilities that handle every scenario—from online transfers to dead computer recovery.
Resources
- How Customers Deactivate Licenses
- Clearing License Keys from Systems
- Dead Computer Deactivation
- Deactivation Verification Codes
- QLM Self-Service Portal
- Download QLM
How do you handle license transfers? Have you had dead computer nightmares? Share in the comments! 💬
Top comments (0)