How to add licence keys with an HWID lock to a C# or VB.NET app
Add licence keys, a one-PC lock and a live kill switch to a WinForms, WPF or console app in C# or VB.NET with the free PWFAuth NuGet package: install it, sign in, start the heartbeat and move a licence to a new PC
The PWFAuth NuGet package does the hard parts for you: the encryption, the heartbeat and the kill switch. It targets .NET Standard 2.0 and .NET 8, so it works in WinForms, WPF and console apps on .NET Framework 4.6.2 and newer, in C# and in VB.NET. This guide takes you from an empty panel to a program that only opens with a valid key
Step 1: create the application
Sign in to your panel, open Applications and press New application. Give it a name: the app secret is made for you. Your program needs that secret to talk to PWF Auth
Step 2: install the package
In Visual Studio open Project → Manage NuGet Packages, search for PWFAuth and install it. Use version 1.5.0 or newer: every reply from the server is signed, and older versions carry an older key that the current server refuses
Step 3: keep the secret out of your code
Read the app secret at start-up instead of writing it in the source, for example from App.config:
<appSettings>
<add key="PWFAuthAppSecret" value="your app secret" />
</appSettings>An environment variable works just as well. Either way, the secret never sits in your source control
Step 4: sign in and start the heartbeat
Sign the customer in with their key. When it works, start the heartbeat and open your main window. SessionEnded is your kill switch: it fires when the key is banned, paused, expired, deleted or reset, when you end the session from the panel, and when the server cannot be reached three times in a row
using PWFAuth;
var client = new PwfClient(secret);
client.SessionEnded += (s, e) =>
{
MessageBox.Show(e.Message, "Signed out");
Application.Exit();
};
var login = await client.LoginAsync(txtKey.Text.Trim());
if (!login.Success) { lblStatus.Text = login.Message; return; }
client.StartHeartbeat(); // the kill switch: never skip itThe same in VB.NET:
Imports PWFAuth
Public Class FormLogin
Public Shared Client As PwfClient
Private Async Sub btnSignIn_Click(sender As Object, e As EventArgs) Handles btnSignIn.Click
Client = New PwfClient(ConfigurationManager.AppSettings("PWFAuthAppSecret"))
AddHandler Client.SessionEnded, Sub(s, args)
MessageBox.Show(args.Message, "Signed out")
Application.Exit()
End Sub
Dim login = Await Client.LoginAsync(txtKey.Text.Trim())
If Not login.Success Then
lblStatus.Text = login.Message ' written for the customer
Return
End If
Client.StartHeartbeat()
FormMain.Show()
Hide()
End Sub
End ClassAlways call
StartHeartbeat(). Without it your program never learns that a key was banned, paused or expired
login.Message is written for the customer, so you can show it as it is. The sign-in reply also carries the licence itself: user.expires_at (empty for a lifetime key), user.days_remaining, user.key_type, and your app's name, version and welcome message
Step 5: move a licence to a new PC
A key is bound to the first PC that signs in with it. When a customer changes PC, the sign-in answers HWID_MISMATCH (or DEVICE_LIMIT for a key allowed on several PCs). If you turned on self-service resets for the app, your program can offer to move the licence:
if (!login.Success && (login.ErrorCode == PwfErrorCodes.HwidMismatch ||
login.ErrorCode == PwfErrorCodes.DeviceLimit))
{
var reset = await client.ResetHardwareIdAsync(key, "Moved to a new PC");
MessageBox.Show(reset.Message);
if (reset.Success) login = await client.LoginAsync(key);
}Customer accounts instead of keys
Prefer a username and a password? AccountLoginAsync(username, password) signs a customer account in, with the same session and the same kill switch. Customers can sign up from your program, and add a key's time to their account with RedeemKeyAsync
Step 6: make keys and test
Back in the panel, open Licences and generate a few keys. Run your program, type a key and you're in. Open Sessions to see the copy live, then ban the key: within 30 seconds the program closes and tells the customer why
More you can do
CreateTrialAsync(): a free trial key for this PC, when trials are onCheckUpdateAsync(version): is there a newer build to download?GetTextsAsync()andGetSlidesAsync(): words and announcements you change from the panel, without a new buildSetVariableAsyncandGetVariableAsync: values kept on the server for each customer
The full reference is in C# and VB.NET


