Distromate Docs

C# 接入

适用于 .NET 应用程序和 Unity 游戏

准备工作

  1. 获取 dm_api.dllDmApi.cs 文件
  2. 将 DLL 文件放置在程序运行目录
  3. 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)

参数:

参数类型描述
publicKeyPemstringPEM 格式的 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)

参数:

参数类型描述
pipeNamestringPipe 名称,格式: \\.\pipe\<name>
timeoutMsuint超时时间(毫秒),默认 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 集成

设置

  1. dm_api.dll 放入 Assets/Plugins/x86_64/ 目录
  2. 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>

注意事项

  1. DmApi 实现了 IDisposable,建议使用 using 语句或手动调用 Dispose()
  2. C# SDK 内置了 RSA 签名验证功能
  3. 所有 API 调用都是同步的
  4. Unity 中需要注意在主线程调用 API

On this page