7AA7 / 开放文档
返回首页

HostApi 参考

更新于 2026-10-12

I7AA7HostApi* 指针由 pluginInit 传入,插件可保存使用;pluginUninstall 返回后必须视为悬空,严禁再访问。

一、总览

分类方法用途
私有配置getPluginConfig / setPluginConfig按 pluginId 隔离的 KV 持久化
沙箱文件pluginDataDir仅允许写自己的数据目录
文件对话框chooseOpenFile / chooseSaveFile统一风格的导入 / 导出
诊断日志logPlugin统一写入宿主诊断日志
插件间调用callPluginService路由到其他插件的 callService()
环境信息hostVersion / hostQtVersion / isHostDarkMode只读环境
网络中继pluginNetworkPolicy / egressNetworkRequest唯一合法出网通道
托管线程createManagedThread / releaseManagedThread统一生命周期管理

二、配置读写

cpp
QVariant v = hostApi->getPluginConfig(
    "com.company.myplugin", "lastOpenFile", QVariant(QString()));

bool ok = hostApi->setPluginConfig(
    "com.company.myplugin", "lastOpenFile", QStringLiteral("C:/a.txt"));

不同 pluginId 之间严格隔离,A 插件无法读取 B 插件的配置。

三、沙箱文件

cpp
const QString dir = hostApi->pluginDataDir("com.company.myplugin");
// 返回值示例:<程序根目录>/plugins/data/com.company.myplugin/
QFile f(dir + &quot;/records.bin&quot;);
if (f.open(QIODevice::WriteOnly)) { f.write(&quot;...&quot;); f.close(); }

四、文件对话框

cpp
const QString in = hostApi-&gt;chooseOpenFile(
    &quot;com.company.myplugin&quot;, &quot;&quot;, &quot;Text (*.txt);;All (*.*)&quot;);
if (in.isEmpty()) return; // 用户取消

const QString out = hostApi-&gt;chooseSaveFile(
    &quot;com.company.myplugin&quot;, &quot;&quot;, &quot;output.txt&quot;, &quot;Text (*.txt)&quot;);

五、诊断日志

cpp
hostApi-&gt;logPlugin(&quot;com.company.myplugin&quot;, &quot;INFO&quot;, &quot;&quot; + path);

级别允许:INFO / WARN / ERROR / DEBUG。日志写入 diag/plugins/<pluginId>.log,用户可在「插件管理 → 查看日志」查看。

六、环境信息(只读)

cpp
const QString hostVer = hostApi-&gt;hostVersion();    // 如 "2.2.7"
const QString qtVer   = hostApi-&gt;hostQtVersion();  // 如 "6.11.1"
const bool    dark    = hostApi-&gt;isHostDarkMode();

建议在 getPluginWidget 中根据 isHostDarkMode() 切换配色。

七、网络中继(唯一合法出网通道)

插件禁止自行使用 QNetworkAccessManager 直连网络。所有出网请求必须经 egressNetworkRequest 中继:宿主用国密加密信封交给服务端代发,响应加密回传。

第一步,在元信息中声明:

json
&quot;extra&quot;: {
  &quot;network_access&quot;: true,
  &quot;network_domains&quot;: [&quot;api.example.com&quot;]
}

第二步,查询授权状态:

cpp
using Policy = I7AA7HostApi::PluginNetworkPolicy;
const Policy p = hostApi-&gt;pluginNetworkPolicy(&quot;com.company.myplugin&quot;);
// Denied / Allowed / NeedConsent

第三步,发起请求(异步回调):

cpp
hostApi-&gt;egressNetworkRequest(
    &quot;com.company.myplugin&quot;, &quot;POST&quot;, &quot;https://api.example.com/v1/tasks",
    { {&quot;Content-Type&quot;, &quot;application/json&quot;} },
    QByteArray(R&quot;({&quot;q&quot;:&quot;hello&quot;})&quot;),
    [](const I7AA7HostApi::PluginEgressResult&amp; r) {
        if (!r.success) { /* r.error */ return; }
        // r.httpStatus / r.body / r.headers
    });

中继安全约束(宿主强制):仅 HTTPS;禁止 IP 字面量(防 SSRF);禁止 localhost/.local/.internal 等主机名;network_domains 非空时强制后缀匹配;方法仅 GET/POST/PUT/DELETE。

八、托管线程

cpp
QThread* t = hostApi-&gt;createManagedThread(&quot;com.company.myplugin&quot;, &quot;worker&quot;);
if (t) {
    auto* w = new MyWorker;
    w-&gt;moveToThread(t);
    t-&gt;start();
    // 插件卸载时宿主自动回收;也可手动:
    // hostApi->releaseManagedThread("com.company.myplugin", t);
}

老版本宿主返回 nullptr(安全降级),插件须处理。