跳到主要内容

GST Licensing 機台綁定指南

本文件說明 GST.Core.Licensing 的架構、Machine Fingerprint 機制與部署流程。

1. 架構總覽​

2. 核心介面​

2.1 ILicenseService​

public interface ILicenseService
{
ILicenseInfo? CurrentLicense { get; }
bool IsLicenseValid();
bool IsFeatureEnabled(string featureCode);
bool IsAnyFeatureEnabled(params string[] featureCodes);
IReadOnlyList<string> GetEnabledFeatures();
int? GetLimit(string limitCode);
bool IsUsbDonglePresent();
Task<LicenseActivationResult> ActivateAsync(string licenseKey);
Task<bool> DeactivateAsync();
}

2.2 ILicenseInfo​

public interface ILicenseInfo
{
string LicenseId { get; }
string CustomerName { get; }
LicenseTier Tier { get; } // Trial/Basic/Standard/Professional/Enterprise
DateTime ExpiresAt { get; }
int DaysRemaining { get; }
bool IsExpired { get; }
bool IsTrial { get; }
LicenseBindingMode BindingMode { get; }
}

2.3 LicenseBindingMode​

[Flags]
public enum LicenseBindingMode
{
None = 0,
Machine = 1, // 綁定硬體 Fingerprint
UsbDongle = 2, // 綁定 USB Dongle
MachineOrUsb = 3, // 擇一(彈性)
MachineAndUsb = 4, // 兩者都需要(嚴格)
Online = 8 // 需線上驗證
}

3. Machine Fingerprint​

3.1 組成​

元件WMI Query範例
CPU IDWin32_Processor.ProcessorIdBFEBFBFF000A0653
Motherboard SerialWin32_BaseBoard.SerialNumberDBBGV1100120700A379100
BIOS SerialWin32_BIOS.SerialNumberUDBGXTA00K221008170001
HDD SerialWin32_DiskDrive.SerialNumber(Index=0)0000_0000_...
MAC AddressNetworkInterface.GetPhysicalAddress()(最高速非 Loopback)2C-0D-A7-B4-3B-FB

3.2 Combined Hash​

CombinedHash = SHA256(UTF8("{CpuId}|{MotherboardSerial}|{BiosSerial}|{HddSerial}"))

僅非空元件參與 Hash 計算。

3.3 容錯機制​

public bool Matches(MachineFingerprint other, int tolerance = 1)

預設容許 1 個元件不符,處理硬體更換(如換網卡、換硬碟)的情境。

4. USB Dongle 支援​

4.1 偵測方式​

Win32_DiskDrive (InterfaceType='USB')
→ Win32_DiskDriveToDiskPartition
→ Win32_LogicalDiskToPartition
→ 取得 DriveLetter, SerialNumber, VID/PID

4.2 UsbDeviceInfo​

public record UsbDeviceInfo
{
public required string DeviceId { get; init; }
public required string SerialNumber { get; init; }
public string VolumeLabel { get; init; }
public string DriveLetter { get; init; }
public string VendorId { get; init; } // USB VID
public string ProductId { get; init; } // USB PID
}

5. Metalama Aspect 整合​

5.1 [LicenseCheck] — 驗證 License 存在​

[LicenseCheck]
public void PerformCriticalOperation() { /* ... */ }
// 無有效 License → 拋出 LicenseException

[LicenseCheck(ThrowOnFailure = false)]
public void PerformOptionalOperation() { /* ... */ }
// 無有效 License → 回傳 default,不拋例外

5.2 [LicenseRequired] — 驗證特定 Feature​

[LicenseRequired("AdvancedReporting")]
public Report GenerateAdvancedReport() { /* ... */ }
// Feature 未啟用 → 拋出 LicenseException

6. DI 註冊​

services.AddLicensing(options =>
{
options.LicenseFilePath = Path.Combine(configDir, "license.lic");
options.ThrowOnLicenseFailure = false;
options.BackgroundCheckIntervalMinutes = 30;
options.FingerprintTolerance = 1; // 容許 1 個硬體元件不符
options.AllowOfflineMode = true; // 支援離線環境
});

7. 部署流程​

7.1 全新部署​

1. 在目標機台執行應用程式
└→ 應用程式偵測無 License
└→ 匯出 hardware-id.txt(含 CombinedHash)

2. 使用者將 hardware-id.txt 傳給開發團隊

3. 開發團隊使用 .NET Reactor License Manager 產生 license.lic
└→ 綁定該機台的 Hardware ID

4. 將 license.lic 放到 %APPDATA%\{AppName}\license.lic

5. 重新啟動應用程式 → 驗證通過

7.2 License 檔案位置​

%APPDATA%\ProcessVision\license.lic

7.3 App.xaml.cs 載入順序​

// 1. 複製 License 檔(在 DI 之前,Reactor 保護 DLL 載入前)
CopyLicenseFiles();

// 2. DI 註冊 AddLicensing()

// 3. 初始化 AspectServiceLocator(啟用 Aspect 注入)
AspectServiceLocator.Initialize(Services);

// 4. 驗證 License 狀態
CheckLicenseStatus();

// 5. 若無 License,匯出 Hardware ID
ExportHardwareId();

8. Debug vs Release 行為​

情境DebugRelease
無 License靜默允許所有功能顯示倒數視窗 / 限制功能
ValidatorDevelopmentLicenseValidator(全通過)LicenseValidator(Reactor 驗證)
Feature Check全部 enabled依 License KeyValue 判斷

9. .NET Reactor Hardware Lock 差異​

GST.Core.Licensing.NET Reactor Hardware Lock
層級應用層DLL 保護層
綁定方式SHA256 FingerprintReactor 內建 HID
容錯支援(tolerance 參數)不支援
Feature 控制支援(KeyValue)不支援
用途應用授權管理防止 DLL 複製執行

兩者是獨立機制,可同時使用。

10. 常見問題​

10.1 License 驗證失敗​

  1. 確認 license.lic 在正確路徑(%APPDATA%\{AppName}\)
  2. 確認 License 未過期
  3. 確認硬體未大幅更換(超過 tolerance 容許)
  4. 檢查 hardware-id.txt 是否與 License 對應

10.2 硬體更換後 License 失效​

更換超過 1 個硬體元件(如同時換主機板 + 硬碟)會導致 Fingerprint 不符。需重新匯出 Hardware ID 並產生新 License。

10.3 離線環境(Air-Gapped)​

ValidateOnlineAsync() 目前回傳 true(不需網路),專為工廠離線環境設計。


文件版本:v1.0 | 建立日期:2026-03-16 | 對應 Issue:GST-172