I7AA7HostApi* 指针由 pluginInit 传入,插件可保存使用;pluginUninstall 返回后必须视为悬空,严禁再访问。
一、总览
| 分类 | 方法 | 用途 |
|---|---|---|
| 私有配置 | getPluginConfig / setPluginConfig | 按 pluginId 隔离的 KV 持久化 |
| 沙箱文件 | pluginDataDir | 仅允许写自己的数据目录 |
| 文件对话框 | chooseOpenFile / chooseSaveFile | 统一风格的导入 / 导出 |
| 诊断日志 | logPlugin | 统一写入宿主诊断日志 |
| 插件间调用 | callPluginService | 路由到其他插件的 callService() |
| 环境信息 | hostVersion / hostQtVersion / isHostDarkMode | 只读环境 |
| 网络中继 | pluginNetworkPolicy / egressNetworkRequest | 唯一合法出网通道 |
| 托管线程 | createManagedThread / releaseManagedThread | 统一生命周期管理 |
二、配置读写
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 插件的配置。
三、沙箱文件
const QString dir = hostApi->pluginDataDir("com.company.myplugin");
// 返回值示例:<程序根目录>/plugins/data/com.company.myplugin/
QFile f(dir + "/records.bin");
if (f.open(QIODevice::WriteOnly)) { f.write("..."); f.close(); }四、文件对话框
const QString in = hostApi->chooseOpenFile(
"com.company.myplugin", "", "Text (*.txt);;All (*.*)");
if (in.isEmpty()) return; // 用户取消
const QString out = hostApi->chooseSaveFile(
"com.company.myplugin", "", "output.txt", "Text (*.txt)");五、诊断日志
hostApi->logPlugin("com.company.myplugin", "INFO", "" + path);级别允许:INFO / WARN / ERROR / DEBUG。日志写入 diag/plugins/<pluginId>.log,用户可在「插件管理 → 查看日志」查看。
六、环境信息(只读)
const QString hostVer = hostApi->hostVersion(); // 如 "2.2.7"
const QString qtVer = hostApi->hostQtVersion(); // 如 "6.11.1"
const bool dark = hostApi->isHostDarkMode();建议在 getPluginWidget 中根据 isHostDarkMode() 切换配色。
七、网络中继(唯一合法出网通道)
插件禁止自行使用 QNetworkAccessManager 直连网络。所有出网请求必须经 egressNetworkRequest 中继:宿主用国密加密信封交给服务端代发,响应加密回传。
第一步,在元信息中声明:
"extra": {
"network_access": true,
"network_domains": ["api.example.com"]
}第二步,查询授权状态:
using Policy = I7AA7HostApi::PluginNetworkPolicy;
const Policy p = hostApi->pluginNetworkPolicy("com.company.myplugin");
// Denied / Allowed / NeedConsent第三步,发起请求(异步回调):
hostApi->egressNetworkRequest(
"com.company.myplugin", "POST", "https://api.example.com/v1/tasks",
{ {"Content-Type", "application/json"} },
QByteArray(R"({"q":"hello"})"),
[](const I7AA7HostApi::PluginEgressResult& 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。
八、托管线程
QThread* t = hostApi->createManagedThread("com.company.myplugin", "worker");
if (t) {
auto* w = new MyWorker;
w->moveToThread(t);
t->start();
// 插件卸载时宿主自动回收;也可手动:
// hostApi->releaseManagedThread("com.company.myplugin", t);
}老版本宿主返回 nullptr(安全降级),插件须处理。