All posts

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

3 min read

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 it

The 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 Class

Always 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 on
  • CheckUpdateAsync(version): is there a newer build to download?
  • GetTextsAsync() and GetSlidesAsync(): words and announcements you change from the panel, without a new build
  • SetVariableAsync and GetVariableAsync: values kept on the server for each customer

The full reference is in C# and VB.NET

Protect your app for free

Licence keys, customer accounts and the kill switch, in every language. Make an account and sign in with your first key in a few minutes

Create a free account