Go 接入
使用 Go 语言集成 DistroMate SDK
准备工作
- 获取
dm_api.dll和dm_api.go文件 - 将 DLL 文件放置在程序运行目录
- 将
dm_api.go添加到项目中
依赖
- Go 1.18 或更高版本
- Windows 平台(使用 syscall 调用 DLL)
导入包
import "your_project/dmapi"快速开始
package main
import (
"fmt"
"your_project/dmapi"
)
const publicKey = `
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...
-----END PUBLIC KEY-----
`
func main() {
// 创建 API 实例
api, err := dmapi.New(publicKey, "dm_api.dll")
if err != nil {
fmt.Println("Failed to initialize:", err)
return
}
// 1. 检查是否由 Launcher 启动
if api.RestartAppIfNecessary() {
// Launcher 已启动,退出当前进程
return
}
// 2. 连接到 Launcher
if !api.Connect(`\\.\pipe\distromate_pipe`, 5000) {
fmt.Println("Connection failed")
return
}
defer api.Close()
// 3. 验证许可证
data := api.Verify()
if data == nil {
fmt.Println("Verification failed")
return
}
fmt.Println("License verified!")
// 访问许可证数据
if licenseKey, ok := data["license_key"].(string); ok {
fmt.Println("License:", licenseKey)
}
if expiresAt, ok := data["expires_at"].(string); ok {
fmt.Println("Expires:", expiresAt)
}
// 4. 通知初始化完成
if !api.Initiated() {
fmt.Println("Failed to notify initiated")
}
// 应用主逻辑...
fmt.Println("Application running...")
}API 参考
New
创建新的 DmApi 实例。
func New(publicKeyPEM string, dllPath string) (*DmApi, error)参数:
| 参数 | 类型 | 描述 |
|---|---|---|
publicKeyPEM | string | PEM 格式的 RSA 公钥 |
dllPath | string | DLL 文件路径,空字符串表示使用默认路径 dm_api.dll |
返回值:
- 成功:
*DmApi实例 - 失败:
nil和错误信息
RestartAppIfNecessary
检查程序是否由 Launcher 启动,如果不是则通过 Launcher 重启。
func (api *DmApi) RestartAppIfNecessary() bool返回值:
true: 已启动 Launcher,当前进程应退出false: 程序由 Launcher 启动,无需重启
Connect
连接到 Launcher。
func (api *DmApi) Connect(pipe string, timeout uint32) bool参数:
| 参数 | 类型 | 描述 |
|---|---|---|
pipe | string | Pipe 名称,格式: \\.\pipe\<name> |
timeout | uint32 | 超时时间(毫秒) |
返回值: 连接是否成功
Close
关闭与 Launcher 的连接。
func (api *DmApi) Close()Verify
验证许可证。自动生成 nonce 并验证响应签名。
func (api *DmApi) Verify() map[string]interface{}返回值:
- 成功: 包含许可证数据的 map
- 失败:
nil
Activate
激活许可证。自动生成 nonce 并验证响应签名。
func (api *DmApi) Activate() map[string]interface{}返回值: 同 Verify
Initiated
通知 Launcher 程序初始化完成。
func (api *DmApi) Initiated() bool返回值: 操作是否成功
完整示例
package main
import (
"fmt"
"os"
"your_project/dmapi"
)
const publicKey = `
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...
-----END PUBLIC KEY-----
`
func main() {
if err := run(); err != nil {
fmt.Fprintln(os.Stderr, "Error:", err)
os.Exit(1)
}
}
func run() error {
// 初始化 API
api, err := dmapi.New(publicKey, "")
if err != nil {
return fmt.Errorf("init failed: %w", err)
}
// 检查启动方式
if api.RestartAppIfNecessary() {
fmt.Println("Restarting via launcher...")
return nil
}
// 连接
if !api.Connect(`\\.\pipe\distromate_pipe`, 5000) {
return fmt.Errorf("connection failed")
}
defer api.Close()
fmt.Println("Connected to launcher")
// 验证
data := api.Verify()
if data == nil {
return fmt.Errorf("verification failed")
}
// 解析许可证信息
fmt.Println("License verified!")
printLicenseInfo(data)
// 通知完成
if !api.Initiated() {
fmt.Println("Warning: failed to notify initiated")
}
// 应用主逻辑...
fmt.Println("Application running...")
return nil
}
func printLicenseInfo(data map[string]interface{}) {
if userName, ok := data["user_name"].(string); ok {
fmt.Println("User:", userName)
}
if productId, ok := data["product_id"].(string); ok {
fmt.Println("Product:", productId)
}
if expiresAt, ok := data["expires_at"].(string); ok {
fmt.Println("Expires:", expiresAt)
}
if features, ok := data["features"].([]interface{}); ok {
fmt.Println("Features:")
for _, feature := range features {
fmt.Printf(" - %v\n", feature)
}
}
}项目结构
myapp/
├── main.go
├── dmapi/
│ └── dm_api.go
└── dm_api.dll编译
# 编译 Windows 可执行文件
go build -o myapp.exe
# 交叉编译(从其他平台编译 Windows 程序)
GOOS=windows GOARCH=amd64 go build -o myapp.exeGo Modules
// go.mod
module myapp
go 1.18类型断言
由于 Go 是静态类型语言,从 map[string]interface{} 中获取值时需要进行类型断言:
data := api.Verify()
if data == nil {
return
}
// 获取字符串
if licenseKey, ok := data["license_key"].(string); ok {
fmt.Println("License:", licenseKey)
}
// 获取数字
if maxUsers, ok := data["max_users"].(float64); ok {
fmt.Println("Max users:", int(maxUsers))
}
// 获取布尔值
if isActive, ok := data["is_active"].(bool); ok {
fmt.Println("Active:", isActive)
}
// 获取数组
if features, ok := data["features"].([]interface{}); ok {
for _, f := range features {
if feature, ok := f.(string); ok {
fmt.Println("Feature:", feature)
}
}
}
// 获取嵌套对象
if metadata, ok := data["metadata"].(map[string]interface{}); ok {
if version, ok := metadata["version"].(string); ok {
fmt.Println("Version:", version)
}
}注意事项
- Go SDK 内置了 RSA 签名验证功能
- DLL 只能在 Windows 平台上加载
- 所有 API 调用都是同步的
- 使用
defer api.Close()确保连接被正确关闭 - JSON 数字默认解析为
float64类型