1. 準備產品設定與測試授權
為自己的 C#/.NET 或 WinForms 應用程式加入客戶授權碼與功能權限。本教學說明商業軟體的使用授權;為原始碼選擇開源授權條款則是另一項決定。先使用裝置綁定授權與不計量的匯出功能,確認基本流程可正常運作。
裝置額度按目前啟用裝置計算,釋放後返還;一般授權離線仍占用,浮動授權租約到期後自動返還。
- 在控制台「產品」複製產品 ID,點擊同一產品的「簽章公鑰」,將每一組金鑰 ID、公鑰填入初始化程式碼,取代 YOUR_PRODUCT_ID、YOUR_KEY_ID 和 YOUR_PUBLIC_KEY。快速接入也可直接複製已填好的程式碼。無需設定檔;SDK 預設連線至 https://www.licentivo.com。
- 安裝 .NET 8 或更新版本的 SDK。在 Licentivo 快速整合中建立或選擇產品,於策略與授權中允許 export 功能。
2. 安裝固定版本的 .NET 套件
在自己的應用程式專案中執行下方安裝命令或加入建置依賴,安裝 SDK 0.11.6。套件管理器負責取得 SDK,無需下載解壓原始碼套件或設定本機原始碼路徑。
dotnet add package Licentivo.SDK --version 0.11.6dotnet new console --name LicensedApp --framework net8.0
cd LicensedApp
dotnet add package Licentivo.SDK --version 0.11.63. 啟用並保護一個實際操作
將 SDK 初始化接到自己軟體的啟動或啟用入口,從啟用視窗讀取客戶授權碼,傳入產品 ID、信任公鑰並保持用戶端存活。將 RunFeature 放在實際業務入口,以自己的功能取代匯出範例函式。
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;
}
$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 runexport LICENTIVO_LICENSE_KEY='YOUR_TEST_LICENSE_KEY'
dotnet run
# On later starts, restore the saved device credential:
unset LICENTIVO_LICENSE_KEY
dotnet run4. 整合 WinForms 啟用視窗與匯出按鈕
每個匯出入口都 await client.RunFeature("export", ExportReport),包含選單與快捷鍵。操作期間停用對應按鈕,捕捉錯誤並顯示授權拒絕原因,再允許下一次操作。
視窗開啟期間保持用戶端存活,由 SDK 心跳更新授權。背景錯誤提示透過 Invoke 或 BeginInvoke 回到介面執行緒;結束時 await DisposeAsync。正常釋放保留裝置綁定紀錄,並嘗試歸還浮動席位。
獨立桌面範例可透過下方文件連結查看。WinForms 需要 Windows;上方的主控台範例也可在 Linux 與 macOS 執行。
dotnet new winforms --name LicensedWinForms --framework net8.0
cd LicensedWinForms
dotnet add package Licentivo.SDK --version 0.11.6using 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; }
};
}
}
dotnet run5. 驗證啟用、重新啟動及權限拒絕
- 以測試金鑰執行,確認出現 License OK 與 Export completed,並查看匯出檔內容。
- 移除金鑰環境變數,以相同作業系統使用者重新啟動。應恢復既有憑證,不新增註冊裝置。
- 將 LICENTIVO_FEATURE 設為授權中不存在的功能,LICENTIVO_OUTPUT 設為尚不存在的檔名。確認結束碼非零,且沒有產生新檔案。
- 只有策略允許且簽章快取仍有效時才測試離線啟動。浮動授權與必須連線的啟動需要伺服器核准。
排查授權驗證問題
檢查產品 ID、每組金鑰 ID 和公鑰、客戶輸入的授權碼。公鑰屬於產品;客戶授權與本機憑證分別管理。開發測試授權碼及廠商管理 API Key 不隨客戶安裝包發送。
授權到期、裝置上限與功能缺失屬於授權拒絕。顯示錯誤及請求編號,在主控台解決授權或策略問題,不要略過 RunFeature。
每月計次使用 RunMeteredFeature 時保留穩定工作編號與持久業務結果。正常結束與客戶主動 Deactivate 用途不同,不要在每次結束時解除裝置綁定。