Zum Inhalt springen
LICENTIVO / INTEGRATION

C#-Softwarelizenzierung mit .NET und WinForms

Ergänzen Sie eine .NET-8- oder WinForms-App um Lizenzschlüssel. Installieren Sie das SDK über NuGet, schützen Sie Funktionen und prüfen Sie Neustarts und Zugriffsverweigerungen.

.NET 8+ · Konsole und WinFormsAktualisiert

1. Bereiten Sie Produkteinstellungen und eine Testlizenz vor

Ergänzen Sie Ihre C#/.NET- oder WinForms-Anwendung um Kundenlizenzschlüssel und Funktionsberechtigungen. Hier geht es um den Zugriff auf Ihre kommerzielle Software; die Wahl einer Open-Source-Lizenz für den Quellcode ist eine eigene Entscheidung. Beginnen Sie mit einer gerätegebundenen Lizenz und einer Exportfunktion ohne Verbrauchszähler.

Das Gerätekontingent zählt aktuelle Aktivierungen und wird bei Freigabe wieder verfügbar. Normale Lizenzen zählen auch offline; bei Floating-Lizenzen gibt auch ein abgelaufener Lease das Kontingent frei.

  1. Kopieren Sie die Produkt-ID unter Konsole > Produkte. Öffnen Sie die Signaturprüfschlüssel dieses Produkts und tragen Sie alle Schlüssel-ID/Public-Key-Paare im Initialisierungscode ein. Ersetzen Sie YOUR_PRODUCT_ID, YOUR_KEY_ID und YOUR_PUBLIC_KEY. Die Schnellintegration kann den Code erzeugen. Eine Produktkonfigurationsdatei ist nicht erforderlich; das SDK verwendet standardmäßig https://www.licentivo.com.
  2. Installieren Sie .NET 8 SDK oder höher. Erstellen oder wählen Sie in der Licentivo Quick-Integration Ihr Produkt aus und erlauben Sie die Exportfunktion in seiner Richtlinie und Lizenz.

2. Installieren Sie das angepinnte Paket .NET

Installieren Sie SDK 0.11.6 mit dem folgenden Befehl in Ihrem Anwendungsprojekt oder fügen Sie die Build-Abhängigkeit hinzu. Der Paketmanager lädt das SDK; ein Quellcode-ZIP, manuelles Entpacken oder ein lokaler Quellcodepfad ist nicht erforderlich.

Terminal
dotnet add package Licentivo.SDK --version 0.11.6
Terminal · new console project
dotnet new console --name LicensedApp --framework net8.0
cd LicensedApp
dotnet add package Licentivo.SDK --version 0.11.6

3. Aktivieren und schützen Sie einen realen Vorgang

Initialisieren Sie das SDK beim Start oder bei der Aktivierung Ihrer Software. Lesen Sie den Kundenschlüssel aus Ihrem Aktivierungsdialog und übergeben Sie Produkt-ID und vertrauenswürdige Schlüssel. Halten Sie den Client bis zum Beenden offen. Platzieren Sie RunFeature am tatsächlichen Geschäftsaufruf und ersetzen Sie den Export durch Ihre eigene Funktion.

C# · complete Program.cs
using Licentivo;

// BEGIN LICENTIVO PRODUCT
// Copy Product ID and all key ID/public key pairs from Console > Products > Signing public keys.
const string ProductId = "YOUR_PRODUCT_ID";
var TrustedKeys = new Dictionary<string,string> { ["YOUR_KEY_ID"] = "YOUR_PUBLIC_KEY" };
// END LICENTIVO PRODUCT

static string Setting(string name, string fallback) => Environment.GetEnvironmentVariable(name) ?? fallback;

// Call at the business entry point, including shortcuts and alternate menu actions.
static async Task ExportReport(string path)
{
    // Replace this write with your existing, non-metered export operation.
    await File.WriteAllTextAsync(path, "A report generated by the licensed application.\n");
}

try
{
    // In a GUI, read the activation input. Later starts pass an empty key.
    await using var client = await LicentivoClient.OpenProduct(
        ProductId, TrustedKeys, Setting("LICENTIVO_LICENSE_KEY", ""),
        error => Console.Error.WriteLine($"Background verification: {error.Message}"));
    var feature = Setting("LICENTIVO_FEATURE", "export");
    var path = Setting("LICENTIVO_OUTPUT", "licensed-report.txt");
    if (Setting("LICENTIVO_METERED", "") == "1")
        await client.RunMeteredFeature(feature, 1, Setting("LICENTIVO_OPERATION_ID", ""), () => ExportReport(path));
    else
        await client.RunFeature(feature, () => ExportReport(path));
    Console.WriteLine($"License OK: {feature} is available\nExport completed: {path}");
    // Keep client alive in your real app; disposal belongs in app shutdown.
}
catch (Exception error)
{
    Console.Error.WriteLine(error.Message);
    Environment.ExitCode = 2;
}
Windows · PowerShell
$env:LICENTIVO_LICENSE_KEY = 'YOUR_TEST_LICENSE_KEY'
dotnet run
# On later starts, restore the saved device credential:
Remove-Item Env:LICENTIVO_LICENSE_KEY
dotnet run
Linux / macOS · Bash
export LICENTIVO_LICENSE_KEY='YOUR_TEST_LICENSE_KEY'
dotnet run
# On later starts, restore the saved device credential:
unset LICENTIVO_LICENSE_KEY
dotnet run

4. Verbinden Sie die Aktivierung und den Export nach WinForms

Warten Sie an jedem Export-Einstiegspunkt auf client.RunFeature("export", ExportReport). Fügen Sie Menüelemente und Verknüpfungen hinzu. Deaktivieren Sie die Starttaste, während ein Vorgang ausgeführt wird, erkennen Sie Fehler und zeigen Sie die Ablehnung an, bevor Sie einen weiteren Versuch zulassen.

Halten Sie den Client am Leben, während das Fenster geöffnet ist, damit SDK Heartbeats die Autorisierung aktualisieren können. Marsieren Sie Hintergrundfehlermeldungen mit Invoke oder BeginInvoke im UI-Thread. Warten Sie beim Herunterfahren der Anwendung auf DisposeAsync. Die normale Entsorgung behält eine gerätegebundene Registrierung bei und versucht, einen schwebenden Sitz zurückzugeben.

Ein separates Desktopbeispiel finden Sie über den Dokumentationslink unten. WinForms benötigt Windows; das Konsolenbeispiel oben läuft auch unter Linux und macOS.

Windows · new WinForms project
dotnet new winforms --name LicensedWinForms --framework net8.0
cd LicensedWinForms
dotnet add package Licentivo.SDK --version 0.11.6
C# · replace Program.cs
using Licentivo;
namespace LicensedWinForms;
sealed class DemoForm : Form {
    // BEGIN LICENTIVO PRODUCT
    // Console > Products > Signing public keys: paste Product ID and every key ID/public key pair.
    const string ProductId = "YOUR_PRODUCT_ID";
    static readonly Dictionary<string,string> TrustedKeys = new() { ["YOUR_KEY_ID"] = "YOUR_PUBLIC_KEY" };
    // END LICENTIVO PRODUCT
    readonly TextBox key = new() { Width = 380, UseSystemPasswordChar = true };
    readonly Label status = new() { AutoSize = true, MaximumSize = new Size(550, 0), Text = "Enter a key, or leave empty to restore this device." };
    readonly CancellationTokenSource lifetime = new();
    LicentivoClient? client;
    bool busy;
    [STAThread] static void Main() { ApplicationConfiguration.Initialize(); Application.Run(new DemoForm()); }
    DemoForm() {
        Text = "Licentivo · Report export"; ClientSize = new Size(600, 220);
        var panel = new FlowLayoutPanel { Dock = DockStyle.Fill, Padding = new Padding(20), FlowDirection = FlowDirection.TopDown, WrapContents = false, AutoScroll = true };
        Controls.Add(panel); panel.Controls.Add(new Label { Text = "Customer license key", AutoSize = true }); panel.Controls.Add(key);
        Add(panel, "Activate / restore", async () => {
            if (client is not null) { await client.DisposeAsync(); client = null; }
            client = await LicentivoClient.OpenProduct(ProductId, TrustedKeys, key.Text, ct: lifetime.Token);
            key.Clear(); status.Text = client.Status().State;
        });
        var buttons = new FlowLayoutPanel { AutoSize = true, AutoSizeMode = AutoSizeMode.GrowAndShrink, WrapContents = false }; panel.Controls.Add(buttons);
        Add(buttons, "Export CSV", () => Export("export", "report.csv"));
        Add(buttons, "Pro export", () => Export("pro", "pro-report.csv"));
        Add(buttons, "Refresh license", async () => { await Require().RefreshOnline(lifetime.Token); status.Text = Require().Status().State; });
        panel.Controls.Add(status);
        FormClosed += async (_, _) => { lifetime.Cancel(); if (client is not null) await client.DisposeAsync(); };
    }
    LicentivoClient Require() => client ?? throw new InvalidOperationException("Activate the application first.");
    async Task Export(string feature, string filename) {
        using var save = new SaveFileDialog { FileName = filename, Filter = "CSV report|*.csv" };
        await Require().RunFeature(feature, async () => {
            if (save.ShowDialog(this) != DialogResult.OK) return;
            await File.WriteAllTextAsync(save.FileName, "Item,Quantity,Price\nNotebook,2,12.50\nPen,5,3.00\n");
            status.Text = "Saved: " + save.FileName;
        });
    }
    void Add(Control panel, string title, Func<Task> action) {
        var button = new Button { Text = title, AutoSize = true }; panel.Controls.Add(button);
        button.Click += async (_, _) => {
            if (busy) return; busy = true; status.Text = "Working…";
            try { await action(); } catch (Exception error) { if (!IsDisposed) status.Text = error.Message; }
            finally { busy = false; }
        };
    }
}
Windows · PowerShell
dotnet run

5. Überprüfen Sie die Aktivierung, starten Sie neu und verweigern Sie sie

  1. Führen Sie den Test mit Ihrem Testschlüssel aus und bestätigen Sie, dass die Lizenz in Ordnung ist und der Export abgeschlossen ist. Überprüfen Sie dann den Inhalt des Berichts.
  2. Entfernen Sie die Schlüsselumgebungsvariable und starten Sie unter demselben Betriebssystembenutzer neu. Die vorhandenen Geräteanmeldeinformationen sollten ohne ein neues registriertes Gerät wiederhergestellt werden.
  3. Verwenden Sie LICENTIVO_FEATURE, um eine Funktion auszuwählen, die nicht in der Lizenz enthalten ist, und LICENTIVO_OUTPUT, um einen neuen Dateinamen auszuwählen. Bestätigen Sie einen Exit-Code ungleich Null und stellen Sie sicher, dass diese neue Datei niemals erstellt wird.
  4. Überprüfen Sie den Offline-Start nur mit einer Richtlinie, die dies zulässt, und einem gültigen signierten Cache. Floating- und reine Online-Startvorgänge erfordern eine Servergenehmigung.

Beheben Sie Fehler bei Lizenzprüfungen

Prüfen Sie Produkt-ID, alle Schlüssel-ID/Public-Key-Paare und den eingegebenen Lizenzschlüssel. Öffentliche Prüfschlüssel gehören zum Produkt; Kundenlizenzen und Geräteanmeldedaten sind getrennt. Verteilen Sie keine Testschlüssel oder Verwaltungs-API-Keys.

Eine abgelaufene Lizenz, ein Gerätelimit oder eine fehlende Funktion ist eine Verweigerung der Autorisierung. Zeigen Sie die Fehler- und Anforderungs-ID an und lösen Sie die Lizenz oder Richtlinie in der Konsole auf, anstatt RunFeature zu umgehen.

Behalten Sie für monatliche Nutzungslimits eine stabile Job-ID und ein dauerhaftes Geschäftsergebnis bei, wenn Sie RunMeteredFeature aufrufen. Das normale Herunterfahren der App und die vom Kunden angeforderte Deaktivierung haben unterschiedliche Zwecke. Geben Sie nicht bei jedem Exit eine gerätegebundene Registrierung frei.