Skip to content

C# SDK 接入

C# SDK 是第一阶段推荐的标准接入方式,适用于 .NET Framework 4.8、.NET 6 及以上版本的桌面软件、工业上位机、客户端工具和需要本地许可证校验的业务系统。

SDK 仓库地址:cedar-v/license-manager-dotnet

适用场景

  • 希望少处理底层 HTTP 接口、验签和心跳细节。
  • 需要在线激活后在本地保存许可证文件。
  • 需要在程序启动时做本地许可证校验。
  • 需要在运行期通过心跳同步授权状态和授权配置变更。
  • 需要支持 Windows 桌面、WinForms/WPF、控制台服务或其他 .NET 客户端程序。

SDK 信息

项目说明
包名LicenseManager.DotNet
命名空间LicenseManager.DotNetLicenseManager.DotNet.Configuration
默认授权服务https://lic.cedar-v.com
支持框架net48net6.0
核心能力在线激活、本地许可证校验、心跳同步、授权配置更新、硬件指纹采集
示例项目仓库中的 demo/LicenseUiDemo

获取 SDK

如果已经发布到内部或公开 NuGet 源,可以直接安装:

bash
dotnet add package LicenseManager.DotNet

如果当前项目通过源码仓库交付,可以先拉取并打包:

powershell
git clone https://github.com/cedar-v/license-manager-dotnet.git
cd license-manager-dotnet
dotnet build .\license-manager-dotnet.sln
dotnet pack .\license-manager-dotnet\license-manager-dotnet.csproj -c Release

然后在业务项目中引用生成的 .nupkg,或在解决方案中直接引用 SDK 项目。

最小在线接入

在线模式下,首次启动时 SDK 会采集硬件指纹并读取本地许可证;如果本地没有有效许可证,则使用激活码完成在线激活。激活接口返回产品公钥后,SDK 使用它验证许可证并缓存两者,然后启动后台心跳。首次在线激活不需要提前配置公钥。

csharp
using LicenseManager.DotNet;
using LicenseManager.DotNet.Configuration;
var config = new LicenseClientConfig
{
    Server = "https://lic.cedar-v.com",
    Product = "my-product",
    Version = "1.0.0",
    AuthorizationCode = "LIC-XXXX-XXXX",
    LicenseFilePath = "license_code/license.lic",
    HardwareFields = new List<string> { "hostname", "cpu" },
    HeartbeatIntervalSeconds = 600
};

using var client = await LicenseClient.CreateAsync(config);

client.Validate();

var license = client.CurrentLicense();
Console.WriteLine($"授权状态:{license?.Status}");
Console.WriteLine($"到期时间:{license?.ExpiresAt:u}");

接入时建议把 Product 配置为雪松授权云平台中的产品标识,并保持客户端版本号 Version 与实际软件版本一致。

配置项

配置项必填说明
Server在线模式必填授权服务地址,默认使用 https://lic.cedar-v.com
Product产品标识,SDK 会校验许可证中的产品标识是否一致
Version当前软件版本,会随激活和心跳上报
AuthorizationCode首次在线激活必填激活码,也可以通过 AuthorizationCodePath 从文件读取
LicenseFilePath本地许可证文件路径,默认 license_code/license.lic
PublicKeyPath / PublicKeyPem在线首次激活可不填;离线模式必填显式提供产品公钥,适用于纯离线或固定信任根场景
Offline是否启用离线模式
HardwareFields硬件指纹字段,推荐默认 hostnamecpu
HeartbeatIntervalSeconds本地默认心跳间隔;服务端心跳响应可覆盖下一轮间隔
HttpTimeoutSecondsHTTP 超时时间,未配置时默认 15 秒
DeviceInfo激活时上报的设备信息
Metadata激活时上报的扩展信息
HttpHeaders自定义请求头

启动流程

读取授权配置

CurrentLicense() 返回当前许可证载荷副本,业务侧可以读取功能开关、额度限制和自定义授权参数。

csharp
var license = client.CurrentLicense();
if (license == null)
{
    throw new InvalidOperationException("未加载许可证");
}

var features = license.FeatureConfig;
var usageLimits = license.UsageLimits;
var customParameters = license.CustomParameters;

常用字段:

字段用途
LicenseKey许可证 Key,排查心跳和授权问题时使用
AuthorizationCode对应的授权码
HardwareFingerprint许可证绑定的硬件指纹
Status许可证状态
Product产品标识
Version软件版本
StartDate / EndDate授权开始和结束时间
ExpiresAtSDK 当前用于判断过期的时间
FeatureConfig功能开关配置
UsageLimits使用额度限制
CustomParameters业务自定义授权参数
ConfigUpdatedAt授权配置更新时间

心跳与回调

在线模式下,SDK 会自动启动后台心跳。业务也可以手动触发一次心跳:

csharp
var heartbeat = await client.SendHeartbeatAsync();
Console.WriteLine($"心跳状态:{heartbeat.Status}");

建议业务系统配置回调,用于记录日志、提示重新激活或处理授权配置更新。

csharp
var callbacks = new LicenseCallbacks
{
    OnLicenseUpdated = license =>
    {
        Console.WriteLine($"许可证已更新,到期时间:{license.ExpiresAt:u}");
        return Task.CompletedTask;
    },
    OnHeartbeatError = error =>
    {
        Console.WriteLine($"心跳异常:{error.Message}");
        return Task.CompletedTask;
    },
    OnActivationRequired = reason =>
    {
        Console.WriteLine($"需要重新激活:{reason}");
        return Task.CompletedTask;
    },
    OnHeartbeatPing = () =>
    {
        Console.WriteLine("心跳成功");
        return Task.CompletedTask;
    },
};

using var client = await LicenseClient.CreateAsync(config, new LicenseClientOptions
{
    Callbacks = callbacks
});

回调触发规则:

回调触发条件
OnLicenseUpdatedSDK 成功应用新的许可证文件
OnHeartbeatError后台心跳请求异常,或服务端返回非 000000
OnActivationRequired激活失败,或心跳返回 status == "activation_required"
OnHeartbeatPing后台心跳成功返回

错误处理

服务端返回非 000000 时,SDK 会抛出 LicenseApiException。业务侧应读取 Code,不要只判断 HTTP 状态码。

csharp
try
{
    using var client = await LicenseClient.CreateAsync(config);
    client.Validate();
}
catch (LicenseApiException ex)
{
    Console.WriteLine($"接口范围:{ex.Scope}");
    Console.WriteLine($"错误码:{ex.Code}");
    Console.WriteLine($"错误信息:{ex.ApiMessage}");
    Console.WriteLine($"HTTP 状态:{ex.HttpStatusCode}");
}
catch (Exception ex)
{
    Console.WriteLine($"授权初始化失败:{ex.Message}");
}

常见处理建议:

场景建议处理
激活码不存在、过期或产品不匹配提示用户检查激活码和产品版本,必要时联系授权管理员
激活数量已达上限提示释放旧设备或申请增加激活数量
许可证不存在或已撤销停止受控业务能力,并提示重新激活或联系授权管理员
本地验签失败删除异常许可证文件后重新激活
网络不可达如果本地许可证仍有效,可按业务策略继续运行,并记录心跳异常

更完整的错误码和 JSON 示例见 API 总览

离线模式

离线模式适用于无法访问雪松授权云平台的环境。离线模式不会调用在线激活接口,也不会启动后台心跳,因此无法实时同步撤销状态和授权配置变更。

csharp
var config = new LicenseClientConfig
{
    Product = "my-product",
    Version = "1.0.0",
    Offline = true,
    LicenseFilePath = "license_code/license.lic",
    PublicKeyPath = "license_code/license.pubkey",
    HardwareFields = new List<string> { "hostname", "cpu" }
};

using var client = await LicenseClient.CreateAsync(config);
client.Validate();

离线模式要求本地已经存在许可证文件,并通过 PublicKeyPathPublicKeyPem 配置同批交付的产品公钥。在线和离线模式使用同一产品级公钥信任边界。

示例项目

SDK 仓库提供了 WinForms 示例项目:

powershell
git clone https://github.com/cedar-v/license-manager-dotnet.git
cd license-manager-dotnet
dotnet run --project .\demo\LicenseUiDemo\LicenseUiDemo.csproj

示例默认使用:

  • 授权服务:https://lic.cedar-v.com
  • 产品标识:my-product
  • 软件版本:1.0.0
  • 硬件指纹字段:hostnamecpu
  • 心跳间隔:600 秒

下一步