一、写在前面

欢迎加入鸿蒙PC开发者社区,共同打造开发者工具生态:鸿蒙PC开发者社区:https://harmonypc.csdn.net/

项目开源地址:https://atomgit.com/OpenHarmonyPCDeveloper/ohos_KeePassXC

欢迎在PC社区平台申请新建项目:https://atomgit.com/OpenHarmonyPCDeveloper

这篇文章记录的是 KeePassXC 在 HarmonyOS PC / 鸿蒙真机环境中的一次适配过程。

KeePassXC 是一个经典的本地离线密码管理器。它的核心用途是把网站账号、用户名、密码、网址、备注等敏感信息保存到一个加密保险库里,用户只需要记住一个主密码,就可以管理多个账号条目。

原版 KeePassXC 是一个 C++ / Qt 桌面项目,完整版本依赖 KeePassXC 自己的数据库、加密、KDBX 文件格式、密码生成、剪贴板和桌面 UI 能力。它和 Electron 项目不一样,也不是 ArkUI 原生项目。适配鸿蒙 PC 时,关键问题不是“前端资源路径怎么加载”,而是:

  • 怎样让一个 Qt Widgets 桌面程序进入鸿蒙 Stage 模型;
  • 怎样让 native libentry.so 作为 HAP 的 native library 被启动;
  • 怎样让 Qt 界面绘制到鸿蒙 PC 窗口中;
  • 怎样把 Qt for Harmony SDK、QPA 插件和 Qt 动态库打进 HAP;
  • 怎样处理鸿蒙 PC 真机上的窗口焦点、输入框聚焦和应用前后台问题;
  • 怎样先做出一个可运行、可创建、可解锁、可保存的 KeePassXC Harmony Lite 版本。

这条路线的目标很明确:先把 KeePassXC 作为一个 Qt Widgets 应用稳定跑到鸿蒙 PC 真机上,再逐步评估完整 KDBX / Botan / Qt6 栈的深度迁移。

在这里插入图片描述

二、项目背景:KeePassXC 是 Qt/C++ 桌面应用

适配前先看项目性质。

KeePassXC 不是 Electron 应用,也不是 WebView 应用。它的主体是 C++ / Qt 桌面程序,原始桌面版本主要面向 Windows、macOS 和 Linux。完整项目中,UI、数据库、密码生成、剪贴板、加密和自动填充等能力都围绕桌面端 Qt 应用模型组织。

这次适配的工程目录是:

keepassxc-develop/
├── src/
├── share/
├── CMakeLists.txt
└── harmony_pc/
    ├── AppScope/
    │   └── app.json5
    ├── build-profile.json5
    ├── hvigorfile.ts
    ├── oh-package.json5
    └── entry/
        ├── build-profile.json5
        └── src/main/
            ├── cpp/
            │   ├── CMakeLists.txt
            │   └── keepassxc_harmony_smoke.cpp
            ├── ets/
            │   ├── abilitystage/
            │   ├── entryability/
            │   └── pages/
            ├── module.json5
            └── resources/

鸿蒙侧的新增工程集中在 harmony_pc/ 中。它不是要把整个 KeePassXC 重写成 ArkUI,而是先搭一个 HarmonyOS Stage 工程壳,再在 native 层启动 Qt Widgets 应用。

当前适配里最核心的文件是:

harmony_pc/entry/src/main/cpp/keepassxc_harmony_smoke.cpp
harmony_pc/entry/src/main/cpp/CMakeLists.txt
harmony_pc/entry/build-profile.json5
harmony_pc/AppScope/app.json5

其中 keepassxc_harmony_smoke.cpp 一开始只是一个 smoke test 窗口。适配过程中,它被逐步改造成了一个 KeePassXC Harmony Lite 应用,负责本地保险库创建、主密码解锁、条目编辑、保存和密码生成。

在这里插入图片描述

三、路线选择:借鉴 KTouch 的 Qt for Harmony 适配思路

适配 KeePassXC 时,参考了之前 ok-ktouch-master 的 Qt for Harmony 适配工程。

这里要特别区分:参考的是 KTouch 的 Qt Harmony SDK、Stage 工程组织方式和 native Qt 启动思路,不是把 KTouch 项目本身拿来运行。最终真机上安装的包仍然是 KeePassXC:

bundleName: org.keepassxc.keepassxc
Ability:    EntryAbility
Module:     entry

AppScope/app.json5 中应用信息配置为:

{
  "app": {
    "bundleName": "org.keepassxc.keepassxc",
    "vendor": "KeePassXC",
    "versionCode": 1000000,
    "versionName": "1.0.1-ohos-lite",
    "icon": "$media:layered_image",
    "label": "$string:app_name"
  }
}

鸿蒙工程的设备类型面向 PC / 平板:

"deviceTypes": [
  "2in1",
  "tablet"
]

Qt SDK 通过 entry/build-profile.json5 的 CMake 参数传入:

"arguments": "-DQT_PREFIX=~/XM/ok-ktouch-master/harmony_pc/qtforharmony_sdk"

这一点是整个适配能跑起来的基础。QT_PREFIX 需要指向 Qt for Harmony SDK,否则 CMake 找不到 Qt5Config.cmake、Qt Widgets、Qt OhExtras 和 QPA 平台插件。

本次选择的第一阶段路线是:

  1. 不重写 ArkUI 主界面;
  2. 不一次性迁完整 KeePassXC KDBX 栈;
  3. 先用 Harmony Stage 工程承载 Qt Widgets;
  4. 用 C++ 实现一个 KeePassXC Harmony Lite;
  5. 真机验证创建、解锁、编辑、保存和重启恢复;
  6. 再根据后续目标决定是否继续迁完整 KeePassXC。

这条路线适合快速验证 Qt 桌面工具在鸿蒙 PC 上的窗口、输入、构建、安装和运行链路。

在这里插入图片描述

四、鸿蒙工程壳:Stage Ability + native Qt Widgets

鸿蒙侧仍然是标准 Stage 工程。EntryAbility 负责创建应用窗口,native 侧负责启动 Qt 应用。

在 Qt 程序入口中,创建的是 QApplicationQMainWindow

int runKeePassXCHarmony(int argc, char** argv)
{
    QApplication app(argc, argv);
    QApplication::setApplicationName(QStringLiteral("KeePassXC"));
    QApplication::setApplicationDisplayName(QStringLiteral("KeePassXC"));
    QApplication::setOrganizationDomain(QStringLiteral("keepassxc.org"));
    QApplication::setApplicationVersion(QStringLiteral("1.0.1-ohos-lite"));

    auto* window = new MainWindow();
    window->setAttribute(Qt::WA_DeleteOnClose);

#if defined(Q_OS_OPENHARMONY)
    auto* windowHelper = new QOhWidgetHelper(window, window);
    windowHelper->setSupportedWindowModes(
        QOhWidgetHelper::FULL_SCREEN |
        QOhWidgetHelper::SPLIT |
        QOhWidgetHelper::FLOATING
    );
    windowHelper->setWindowRectAutoSave(true);
#endif

    window->show();
    QTimer::singleShot(0, window, [window]() {
        window->activateWindow();
        window->raise();
        window->startVaultFlow();
    });

    return app.exec();
}

QOhWidgetHelper 是 Qt for Harmony 里非常关键的一层,它负责让 Qt Widgets 窗口更好地适配鸿蒙 PC 的窗口模式,包括全屏、分屏、悬浮窗口和窗口位置保存。

CMakeLists.txt 中把 native 入口编译成 entry

add_library(entry SHARED
    keepassxc_harmony_smoke.cpp
)

target_compile_features(entry PRIVATE cxx_std_17)
target_compile_definitions(entry PRIVATE
    KEEPASSXC_HARMONY_SMOKE
    OPENHARMONY
    NAPI_DISABLE_CPP_EXCEPTIONS
)

链接的 Qt 模块包括:

Qt5::Core
Qt5::Gui
Qt5::OhExtras
Qt5::Widgets
Qt5::QOpenHarmonyPlatformIntegrationPlugin
Qt5::QGifPlugin
Qt5::QICOPlugin
Qt5::QJpegPlugin

这里的适配重点是:KeePassXC Harmony Lite 当前使用的是 Qt Widgets,所以必须带上 Qt5::Widgets 和 OpenHarmony 平台插件 Qt5::QOpenHarmonyPlatformIntegrationPlugin。如果只带 Core / Gui,native 库能编译,但界面无法以桌面窗口的方式正常显示。


五、本地保险库:先做可用的 Harmony Lite

完整 KeePassXC 的 KDBX 兼容迁移不是第一阶段目标。为了先把真机可用链路跑通,这次实现了一个本地加密保险库格式:

/data/storage/el2/base/files/keepassxc-harmony.kxvault

当前保险库能力包括:

  • 创建本地密码保险库;
  • 使用主密码解锁;
  • PBKDF2-HMAC-SHA256 派生密钥;
  • ChaCha20 加密 payload;
  • HMAC-SHA256 校验完整性;
  • JSON 保存条目数据;
  • 新增、删除、编辑条目;
  • 保存保险库;
  • 生成随机密码;
  • 复制用户名和密码;
  • 剪贴板 30 秒后自动清空。

条目结构如下:

struct VaultEntry
{
    QString id;
    QString title;
    QString username;
    QString password;
    QString url;
    QString notes;
    QString created;
    QString modified;
};

保存时,明文条目会先组装为 JSON,再加密写入 .kxvault。打开保险库时,会重新派生密钥、校验 HMAC,再解密 payload。

需要强调的是:

.kxvault 不是 .kdbx

它是为了鸿蒙 PC 第一阶段可用性验证实现的本地加密格式。后续如果要兼容原版 KeePassXC,就需要继续迁移 KDBX 文件格式、数据库模型和完整加密栈。


六、真机问题一:不要把 KTouch 和 KeePassXC 混在一起

这次适配过程中最容易混淆的一点是:Qt for Harmony SDK 和工程模板参考了 KTouch,但真机运行目标必须始终是 KeePassXC。

因此调试时要反复确认包名:

/Applications/DevEco-Studio.app/Contents/sdk/default/openharmony/toolchains/hdc shell bm dump -n org.keepassxc.keepassxc

关键输出应包含:

bundleName: org.keepassxc.keepassxc
versionName: 1.0.1-ohos-lite
cpuAbi: arm64-v8a
compileSdkVersion: 6.0.2.130

启动应用时使用:

/Applications/DevEco-Studio.app/Contents/sdk/default/openharmony/toolchains/hdc shell aa start -b org.keepassxc.keepassxc -a EntryAbility

如果真机上看到的是 KTouch、JD-GUI、Phototonic、Logseq 或其他应用窗口,就要先检查当前前台任务和包名,而不是继续改 KeePassXC 业务代码。


七、真机问题二:创建/解锁弹窗导致窗口焦点异常

最初的创建和解锁流程使用了 QDialog。在普通桌面 Qt 环境里,这种写法没有问题:

QDialog dialog(parent);
dialog.exec();

但在鸿蒙 PC 真机上,Qt 弹窗会变成额外窗口,关闭弹窗或切换主界面时,系统可能把其他前台任务顶上来。实际调试中出现过这种现象:

  • KeePassXC 主窗口还在;
  • 进程 org.keepassxc.keepassxc 也还在;
  • 但是屏幕前景切到了 Logseq / 页面 / 图谱等其他窗口;
  • 用户看起来会以为 KeePassXC 闪退或跳错项目。

最终处理方式是:把创建和解锁流程从额外 QDialog 改成主窗口内置页面。

当前主窗口使用 QStackedWidget 做两种状态:

locked page   解锁 / 创建保险库
vault page    条目列表 / 条目详情

锁定页中直接提供两个区域:

解锁保险库:主密码输入框 + 解锁按钮
创建保险库:名称 + 主密码 + 确认 + 创建按钮

这样启动、创建、解锁都发生在 KeePassXC 自己的主窗口内,不再依赖额外弹窗,真机上的窗口焦点稳定性明显更好。

在这里插入图片描述

八、真机问题三:二级页面输入框点不动

进入主界面后,最初还有一个交互问题:点击右侧的“标题、用户名、密码、网址、备注”没有聚焦,看起来像输入框失效。

原因不是输入法,也不是 Qt 控件本身不可用,而是业务状态机的问题。

早期逻辑里,如果当前没有选中条目,就会执行:

clearEditor();
setEnabledForEntry(false);

setEnabledForEntry(false) 会把这些控件都禁用:

m_title->setEnabled(false);
m_username->setEnabled(false);
m_password->setEnabled(false);
m_url->setEnabled(false);
m_notes->setEnabled(false);

所以用户虽然能看到输入框,但输入框是 disabled 状态,自然点不进去,也不会出现光标。

第一次尝试的修复是“用户输入时自动创建条目”,但这种方案会在 textChanged 信号里重建列表,容易触发 Qt/Harmony 窗口刷新和焦点抖动。最终采用了更稳的方式:

保险库为空时,进入主界面立即创建一个真实的“新条目”,并自动选中它。

核心逻辑是:

if (m_vault.entries().isEmpty()) {
    addEntry(QStringLiteral("新条目"), false);
    statusBar()->showMessage(
        QStringLiteral("已创建新条目,可以直接编辑标题、用户名、密码、网址和备注")
    );
    return;
}

这样右侧详情区从一开始就绑定到一个真实条目,标题、用户名、密码、网址和备注全部是可编辑状态。用户进入二级页面后,不需要先点“新增”,也不会遇到看得到输入框但点不动的问题。

在这里插入图片描述

九、构建、安装和真机运行

本次工程路径:

~/XM/keepassxc-develop/harmony_pc

构建时需要指定 DevEco SDK 环境变量。否则可能遇到 hvigor / SDK 版本不匹配问题,例如:

(0 , hvigor_1.WithParamReplacement) is not a function

最终使用的构建命令是:

cd ~/XM/keepassxc-develop/harmony_pc

env DEVECO_SDK_HOME=/Applications/DevEco-Studio.app/Contents/sdk \
OHOS_BASE_SDK_HOME=/Applications/DevEco-Studio.app/Contents/sdk/default/openharmony \
/Applications/DevEco-Studio.app/Contents/tools/node/bin/node \
/Applications/DevEco-Studio.app/Contents/tools/hvigor/bin/hvigorw.js \
--mode module -p module=entry -p product=default assembleHap \
--analyze=normal --parallel --incremental --no-daemon --stacktrace

签名后的 HAP 路径:

~/XM/keepassxc-develop/harmony_pc/entry/build/default/outputs/default/entry-default-signed.hap

安装到真机:

/Applications/DevEco-Studio.app/Contents/sdk/default/openharmony/toolchains/hdc install -r \
~/XM/keepassxc-develop/harmony_pc/entry/build/default/outputs/default/entry-default-signed.hap

启动应用:

/Applications/DevEco-Studio.app/Contents/sdk/default/openharmony/toolchains/hdc shell aa start \
-b org.keepassxc.keepassxc \
-a EntryAbility

强停应用:

/Applications/DevEco-Studio.app/Contents/sdk/default/openharmony/toolchains/hdc shell aa force-stop org.keepassxc.keepassxc

清理应用数据:

/Applications/DevEco-Studio.app/Contents/sdk/default/openharmony/toolchains/hdc shell bm clean -n org.keepassxc.keepassxc -d

查看安装信息:

/Applications/DevEco-Studio.app/Contents/sdk/default/openharmony/toolchains/hdc shell bm dump -n org.keepassxc.keepassxc

十、真机验证流程

最终真机验证按下面这条路径走:

安装 HAP
-> 启动 KeePassXC
-> 创建本地保险库
-> 自动进入主界面并创建“新条目”
-> 编辑标题、用户名、密码、网址、备注
-> 保存保险库
-> 强停应用
-> 重新启动
-> 输入主密码解锁
-> 确认条目仍然存在

测试时可以使用一组简单数据:

主密码:Passw0rd!26
标题:HarmonyTest
用户名:user@example.com
网址:https://keepassxc.org
备注:Harmony PC device validation entry

保存成功后,左侧摘要会显示条目数量和保存状态,底部状态栏会显示保险库已保存。重启后用同一个主密码解锁,条目能够恢复,说明本地 .kxvault 文件已经写入并可以解密读取。

在这里插入图片描述

十一、当前版本边界和后续方向

这次适配完成的是 KeePassXC 在鸿蒙 PC 真机上的第一阶段可运行版本。它已经解决了几个关键问题:

  • HarmonyOS Stage 工程接入;
  • Qt for Harmony SDK 接入;
  • Qt Widgets native 应用启动;
  • KeePassXC 包名和应用信息替换;
  • HAP 构建、签名、安装;
  • 真机创建保险库;
  • 主密码解锁;
  • 本地加密保存;
  • 条目编辑、保存和恢复;
  • 输入框无法聚焦的问题;
  • 创建 / 解锁弹窗导致窗口焦点异常的问题。

第一阶段最重要的价值是:证明 KeePassXC 这类 Qt/C++ 桌面工具可以通过 Harmony Stage + native Qt Widgets 的方式跑到鸿蒙 PC 真机上,并且可以完成从启动、创建、编辑、保存到重启恢复的核心闭环。


十三、总结

这次 KeePassXC 适配不是一次简单的套壳,也不是 Electron 项目的资源搬运。它更接近一次 Qt 桌面工具在鸿蒙 PC 上的 native 运行验证。

整个过程可以概括为:

识别原项目技术栈
-> 新增 harmony_pc Stage 工程
-> CMake 接入 Qt Widgets / OhExtras / QPA 插件
-> 替换包名和应用信息
-> 实现 KeePassXC Harmony Lite 本地保险库
-> 修复真机窗口焦点和输入框聚焦问题
-> 构建签名 HAP
-> 安装到鸿蒙 PC 真机验证

最终结果是,一个以 org.keepassxc.keepassxc 为包名的 KeePassXC Harmony PC 应用,可以在真机上创建本地密码保险库、编辑密码条目并保存。虽然它还不是完整上游 KeePassXC,但已经具备了第一阶段可运行、可演示、可继续扩展的基础。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐