C# 接入
适用于 .NET 应用程序和 Unity 游戏
准备工作
- 获取
dm_api.dll和DmApi.cs文件 - 将 DLL 文件放置在程序运行目录
- 将
DmApi.cs添加到项目中
依赖
- .NET 6.0 或更高版本
- System.Text.Json (内置)
- System.Security.Cryptography (内置)
命名空间
using DistroMate;快速开始
using System;
using DistroMate;
class Program
{
const string PublicKey = @"
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...
-----END PUBLIC KEY-----
";
static void Main(string[] args)
{
// 1. 检查是否由 Launcher 启动
if (DmApi.RestartAppIfNecessary())
{
// Launcher 已启动,退出当前进程
return;
}
// 2. 创建 API 实例并连接
using var api = new DmApi(PublicKey);
try
{
api.Connect(@"\\.\pipe\distromate_pipe");
}
catch (DmApiException ex)
{
Console.WriteLine($"Connection failed: {ex.Message}");
return;
}
// 3. 验证许可证
var data = api.Verify();
if (data != null)
{
Console.WriteLine("License verified!");
if (data.TryGetPropertyValue("license_key", out var licenseKey))
{
Console.WriteLine($"License: {licenseKey}");
}
if (data.TryGetPropertyValue("expires_at", out var expiresAt))
{
Console.WriteLine($"Expires: {expiresAt}");
}
}
else
{
Console.WriteLine($"Verification failed: {DmApi.GetLastError()}");
return;
}
// 4. 通知初始化完成
api.Initiated();
// 应用主逻辑...
Console.WriteLine("Application running...");
}
}API 参考
DmApi 类
构造函数
public DmApi(string publicKeyPem)参数:
| 参数 | 类型 | 描述 |
|---|---|---|
publicKeyPem | string | PEM 格式的 RSA 公钥 |
异常: ArgumentException - 公钥无效
RestartAppIfNecessary (静态方法)
检查程序是否由 Launcher 启动,如果不是则通过 Launcher 重启。
public static bool RestartAppIfNecessary()返回值:
true: 已启动 Launcher,当前进程应退出false: 程序由 Launcher 启动,无需重启
异常: DmApiException - 操作失败
Version (静态属性)
获取 DLL 版本号。
public static string Version { get; }GetLastError (静态方法)
获取最后一次错误信息。
public static string? GetLastError()Connect
连接到 Launcher。
public void Connect(string pipeName, uint timeoutMs = DefaultTimeoutMs)参数:
| 参数 | 类型 | 描述 |
|---|---|---|
pipeName | string | Pipe 名称,格式: \\.\pipe\<name> |
timeoutMs | uint | 超时时间(毫秒),默认 5000ms |
异常: DmApiException - 连接失败
Close
关闭与 Launcher 的连接。
public void Close()IsConnected
检查是否已连接。
public bool IsConnected { get; }Verify
验证许可证。自动生成 nonce 并验证响应签名。
public JsonObject? Verify()返回值:
- 成功: 包含许可证数据的
JsonObject - 失败:
null
Activate
激活许可证。自动生成 nonce 并验证响应签名。
public JsonObject? Activate()返回值: 同 Verify
Initiated
通知 Launcher 程序初始化完成。
public void Initiated()异常: DmApiException - 操作失败
Dispose
释放资源并关闭连接。
public void Dispose()DmApiException 类
public class DmApiException : Exception
{
public int ErrorCode { get; }
}完整示例
using System;
using System.Text.Json.Nodes;
using DistroMate;
namespace MyApp
{
class Program
{
const string PublicKey = @"
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...
-----END PUBLIC KEY-----
";
static int Main(string[] args)
{
// 检查启动方式
try
{
if (DmApi.RestartAppIfNecessary())
{
return 0; // 退出,让 Launcher 启动程序
}
}
catch (DmApiException ex)
{
Console.WriteLine($"Restart check failed: {ex.Message}");
return 1;
}
using var api = new DmApi(PublicKey);
// 连接
try
{
api.Connect(@"\\.\pipe\distromate_pipe");
Console.WriteLine($"Connected. DLL Version: {DmApi.Version}");
}
catch (DmApiException ex)
{
Console.WriteLine($"Connection failed: {ex.Message}");
return 1;
}
// 验证
var data = api.Verify();
if (data == null)
{
Console.WriteLine($"Verification failed: {DmApi.GetLastError()}");
return 1;
}
// 解析许可证信息
Console.WriteLine("License verified!");
PrintLicenseInfo(data);
// 通知完成
try
{
api.Initiated();
}
catch (DmApiException ex)
{
Console.WriteLine($"Initiated failed: {ex.Message}");
}
// 应用主逻辑...
Console.WriteLine("Application running...");
Console.ReadLine();
return 0;
}
static void PrintLicenseInfo(JsonObject data)
{
if (data.TryGetPropertyValue("user_name", out var userName))
{
Console.WriteLine($"User: {userName}");
}
if (data.TryGetPropertyValue("product_id", out var productId))
{
Console.WriteLine($"Product: {productId}");
}
if (data.TryGetPropertyValue("expires_at", out var expiresAt))
{
Console.WriteLine($"Expires: {expiresAt}");
}
if (data.TryGetPropertyValue("features", out var features) &&
features is JsonArray featuresArray)
{
Console.WriteLine("Features:");
foreach (var feature in featuresArray)
{
Console.WriteLine($" - {feature}");
}
}
}
}
}Unity 集成
设置
- 将
dm_api.dll放入Assets/Plugins/x86_64/目录 - 将
DmApi.cs放入Assets/Scripts/目录
使用示例
using UnityEngine;
using DistroMate;
public class LicenseManager : MonoBehaviour
{
const string PublicKey = @"
-----BEGIN PUBLIC KEY-----
...
-----END PUBLIC KEY-----
";
private DmApi _api;
void Awake()
{
// 在 Unity 中,通常在构建后的 exe 启动时检查
if (DmApi.RestartAppIfNecessary())
{
Application.Quit();
return;
}
}
void Start()
{
_api = new DmApi(PublicKey);
try
{
_api.Connect(@"\\.\pipe\distromate_pipe");
var data = _api.Verify();
if (data != null)
{
Debug.Log("License verified!");
// 继续游戏初始化
_api.Initiated();
}
else
{
Debug.LogError("License verification failed!");
Application.Quit();
}
}
catch (DmApiException ex)
{
Debug.LogError($"DM API Error: {ex.Message}");
Application.Quit();
}
}
void OnDestroy()
{
_api?.Dispose();
}
}项目文件配置
.NET 项目 (.csproj)
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<None Update="dm_api.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>注意事项
DmApi实现了IDisposable,建议使用using语句或手动调用Dispose()- C# SDK 内置了 RSA 签名验证功能
- 所有 API 调用都是同步的
- Unity 中需要注意在主线程调用 API