跳到正文
LICENTIVO / INTEGRATION

为 C/C++ 软件实现离线电脑激活

在目标设备生成申请,用另一台联网电脑取得签名响应,再导入原设备。示例使用共享 C 核心上的 C++ 封装。

离线流程 · C++17更新日期

1. 选择允许离线的策略

适用于首次激活也无法联网的客户电脑。策略需要允许设备绑定模式的离线激活,浮动会话不能使用这条流程首次激活。

启用 export 功能,选择允许离线时长,生成含产品签名公钥的 product.json。授权码由客户输入。期限许可证从服务器批准激活时开始计时,不是从响应文件导入时开始。

2. 安装原生 SDK

在 SDK 文档选择 C 或 C++、操作系统以及官网版本安装命令,使用生成的 CMake 依赖连接自己的项目。原生核心需要兼容的编译器、libcurl 和 OpenSSL;C++ 需要 C++17。

下面示例使用 licentivo.hpp 和 CMake 目标 Licentivo::CPP。配置接入包已带原生演示目标。将 product.json 放在程序旁,或在实际应用中使用绝对路径。

使用预编译 CMake 包时,可用下面的 CMakeLists.txt。执行 cmake -S . -B build -DCMAKE_PREFIX_PATH=SDK_PREFIX,将 SDK_PREFIX 换成安装器输出的 CMake prefix 路径,再执行 cmake --build build --config Release。源码包则按安装器说明使用 add_subdirectory,替代 find_package。

CMakeLists.txt
cmake_minimum_required(VERSION 3.18)
project(offline_app LANGUAGES C CXX)
set(CMAKE_CXX_STANDARD 17)
find_package(Licentivo 0.10 REQUIRED)
add_executable(offline offline.cpp)
target_link_libraries(offline PRIVATE Licentivo::CPP)

3. 用 SDK 导出申请和导入响应

将示例保存为 offline.cpp,加入已配置 SDK 的 CMake 项目。在离线电脑执行 offline request YOUR_LICENSE_KEY,生成 activation.request.json,过程不启动联网客户端。

将申请带到联网电脑,在厂商控制台或已关联邮箱的客户门户上传申请,下载批准的响应,命名为 activation.response.json。将申请和响应一起带回原电脑,执行 offline import YOUR_LICENSE_KEY。

C++17 · offline.cpp
#include "licentivo.hpp"
#include <fstream>
#include <iostream>
#include <iterator>
#include <stdexcept>
#include <string>

std::string readText(const char* path) {
    std::ifstream file(path);
    if (!file) throw std::runtime_error("Cannot read file");
    return {std::istreambuf_iterator<char>(file), {}};
}

int main(int argc, char** argv) {
    try {
        // product.json contains public settings; the key is entered by the customer.
        if (argc < 3) throw std::runtime_error("Usage: offline request|import LICENSE_KEY");
        licentivo::Client client("product.json", argv[2]);
        if (std::string(argv[1]) == "request") {
            std::ofstream file("activation.request.json");
            file << client.OfflineRequest();
            if (!file) throw std::runtime_error("Cannot save request");
            std::cout << "Created activation.request.json\n";
        } else if (std::string(argv[1]) == "import") {
            client.ImportOffline(readText("activation.request.json"),
                                 readText("activation.response.json"));
            client.RunFeature("export", [] {
                std::ofstream file("licensed-report.txt");
                file << "Licensed offline export\n";
                if (!file) throw std::runtime_error("Cannot save report");
            });
            std::cout << "Created licensed-report.txt\n";
        } else {
            throw std::runtime_error("Unknown operation");
        }
    } catch (const std::exception& error) {
        std::cerr << error.what() << '\n';
        return 1;
    }
}

4. 确认激活结果

  1. 确认导入成功并生成 licensed-report.txt。
  2. 在同一缓存位置用已保存的设备凭据重启,仍有效的离线租约应允许已授权功能。
  3. 尝试在另一台普通电脑导入同一响应,设备校验应拒绝。
  4. 检查许可证到期时间与离线时长。导入文件不会延长原许可证,也不能超出签名允许范围。

使用 C 接口

C 应用使用 ln_init_file_with_license 创建未启动的客户端,通过 ln_offline_request 生成申请,调用 ln_import_offline 验证并导入。返回字符串用 ln_free_string 释放,退出用 ln_destroy。配置包中的 C 演示包含这些调用。

完全离线首次激活不要调用 Start 或 ln_open,这些启动接口会尝试联网。不要让业务代码自己解析和验证签名。

常见失败与使用限制

响应无效可能是申请、产品、设备、签名公钥或应用版本不匹配。必须导回生成申请的电脑,不要修改 JSON 内容或关闭签名验证。

申请过期需重新生成并批准。离线租约过期需按策略续期或重新交换批准文件。完全离线时不能进行在线计次的预留和确认。

远程解绑或吊销要等旧设备下一次联网检查才会获知。永久离线的设备不能立即感知服务器变更,设置允许离线时长时要考虑这一点。