pgAdmin4 Electron 鸿蒙 PC 适配全记录:从白屏到连接 PostgreSQL
一、写在前面
欢迎加入鸿蒙PC开发者社区,共同打造开发者工具生态:鸿蒙PC开发者社区:https://harmonypc.csdn.net/
项目开源地址:https://atomgit.com/OpenHarmonyPCDeveloper/ohos_pgAdmin4
欢迎在PC社区平台申请新建项目:https://atomgit.com/OpenHarmonyPCDeveloper
这次鸿蒙 PC 适配没有直接把 Python 运行时、Python 三方依赖、PostgreSQL 客户端工具和 pgAdmin Web 服务全部塞进 HAP,而是采用了更稳的第一阶段方案:
HarmonyOS PC Electron HAP
-> 加载 pgAdmin Electron runtime
-> 访问 Mac 上已经启动的 pgAdmin4 Web 服务
-> 通过 pgAdmin4 连接 PostgreSQL 测试库
也就是说,鸿蒙 PC 侧运行的是 Electron HAP 壳和 pgAdmin 页面;Mac 侧负责启动 pgAdmin4 的 Python Flask 服务。两端通过网络访问,最终验证到可以登录 pgAdmin、展开服务器、连接 PostgreSQL、查看对象树和仪表盘。

二、项目原始结构和适配判断
pgAdmin4 的桌面版并不是“一个窗口加载一个静态页面”这么简单。它的主要结构可以拆成三层:
pgadmin4-master/
├── web/ # pgAdmin4 Web 服务,Python Flask 后端和 React/Webpack 前端资源
├── runtime/ # Electron 桌面运行时,负责启动服务、创建窗口、菜单、下载等桌面能力
├── pkg/ # 打包相关逻辑
├── pkg/ohos/ # 本次新增的鸿蒙资源同步和 HAP 构建脚本
└── ohos_hap/ # 本次新增的 OpenHarmony Electron HAP 工程
传统桌面环境中,pgAdmin runtime 会尝试在本机启动 Python 服务,然后 Electron 窗口加载本机端口,例如:
http://127.0.0.1:5050
但是放到 HarmonyOS PC 的 Electron HAP 里,这条链路会遇到几个问题:
- HAP 内没有现成的 Python 解释器
- pgAdmin Web 服务依赖 Python 包和部分 native 能力
- pgAdmin 还可能依赖 PostgreSQL 客户端工具,例如
psql、pg_dump、pg_restore - Electron 主进程中的部分桌面能力在 OpenHarmony runtime 中表现不同
- HAP 资源路径和普通桌面 Electron 的资源路径不同
因此这次没有一上来做“完全离线桌面版”。如果直接硬攻本地 Python,工作量会变成另一类问题:要验证 child_process.spawn、Python runtime、Python native extension、libpq、数据库工具链和 HAP 签名资源的组合可行性。这个目标可以后续继续做,但不是最快让用户在鸿蒙 PC 上用起来的路线。
本次第一阶段目标更明确:
让 pgAdmin4 在 HarmonyOS PC 上先完整打开、登录、连接数据库并完成基本管理操作。
为此选择外部服务模式:
Mac 启动 pgAdmin4 Server
HarmonyOS PC 安装 Electron HAP
HAP 访问 Mac 上的 pgAdmin4 Server
pgAdmin4 Server 再连接 PostgreSQL 测试库
这种方式的好处是适配风险更可控。Electron HAP 只负责承载 pgAdmin runtime 和页面访问能力,不需要在鸿蒙包里立刻解决完整 Python 生态。
三、建立 OpenHarmony Electron HAP 工程
适配后新增了 ohos_hap/ 目录,核心结构如下:
ohos_hap/
├── AppScope/
├── electron/
│ ├── build-profile.json5
│ ├── hvigorfile.ts
│ ├── libs/arm64-v8a/
│ └── src/main/module.json5
├── web_engine/
│ ├── build-profile.json5
│ ├── hvigorfile.ts
│ └── src/main/resources/resfile/
└── build-profile.json5
pgAdmin runtime 最终会被同步到 HAP 的资源目录:
ohos_hap/web_engine/src/main/resources/resfile/resources/app
这个目录就是 OpenHarmony Electron runtime 加载 Node/Electron 应用的位置。构建时会把 pgAdmin 的 Electron runtime 入口、HTML、JS、CSS、assets 和生产依赖同步进去。
本次新增了两个 pgAdmin 自己的鸿蒙构建脚本:
pkg/ohos/build-package.mjs
pkg/ohos/build-hap.mjs
build-package.mjs 负责生成 resources/app,主要做这些事:
- 清理输出目录
- 拷贝
runtime/assets - 拷贝
runtime/src - 写入 OpenHarmony 专用入口
main.cjs - 写入生产依赖版
package.json - 安装 runtime 生产依赖
- 根据环境变量注入外部 pgAdmin Server 地址
生成的 main.cjs 会设置关键环境变量:
PGADMIN_OPENHARMONY=1
PGADMIN_DISABLE_GPU=1
PGADMIN_EXTERNAL_SERVER_URL=<外部 pgAdmin Server 地址>
build-hap.mjs 负责把 pgAdmin 资源同步到 ohos_hap,然后调用 Hvigor 构建 HAP。项目根目录 Makefile 中增加了两个入口:
ohos-package:
node pkg/ohos/build-package.mjs
ohos-hap:
node pkg/ohos/build-hap.mjs
这样后续构建时只需要执行:
PGADMIN_OHOS_EXTERNAL_SERVER_URL=http://127.0.0.1:5050 make ohos-hap
这里使用 127.0.0.1:5050 不是因为 pgAdmin 服务真的跑在鸿蒙设备内部,而是后面会通过 hdc rport 做 USB 端口反向映射,让鸿蒙 PC 访问自己的 127.0.0.1:5050 时实际连到 Mac 上的 pgAdmin 服务。

四、给 HAP 补权限和入口
pgAdmin HAP 要访问外部服务,必须允许网络访问。鸿蒙模块配置中补了网络相关权限:
ohos_hap/electron/src/main/module.json5
关键权限包括:
ohos.permission.INTERNET
ohos.permission.GET_NETWORK_INFO
如果缺少 INTERNET,HAP 里的 Electron 页面即使启动了,也无法稳定访问外部 pgAdmin Server。表现出来可能不是很直观,有时看起来只是白屏、等待中或者加载失败。
同时,pgAdmin runtime 增加了 OpenHarmony 平台识别逻辑:
runtime/src/js/platform.js
核心判断包括:
const OPENHARMONY_PLATFORMS = new Set(['ohos', 'openharmony', 'harmony']);
并且通过环境变量读取外部服务地址:
export function getExternalServerUrl() {
const serverUrl = process.env.PGADMIN_EXTERNAL_SERVER_URL ||
process.env.PGADMIN_SERVER_URL ||
process.env.PGADMIN_DEV_SERVER_URL;
return normalizeServerUrl(serverUrl);
}
这样 HAP 包可以在构建时写死一个默认 pgAdmin Server URL,也可以在没有 URL 时弹出配置页让用户手动输入。
五、Mac 侧启动 pgAdmin4 Server
鸿蒙 PC 侧暂时不内置 Python,所以 Mac 侧需要先把 pgAdmin4 Web 服务启动起来。
本次测试使用的 pgAdmin 配置文件是:
~/XM/pgadmin4-master/web/config_local.py
内容如下:
import os
SERVER_MODE = True
DEFAULT_SERVER = '0.0.0.0'
DEFAULT_SERVER_PORT = 5050
DATA_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '.pgadmin-test-data'))
MASTER_PASSWORD_REQUIRED = False
ENHANCED_COOKIE_PROTECTION = False
UPGRADE_CHECK_ENABLED = False
这里有几个关键点:
SERVER_MODE = True:按服务模式启动 pgAdminDEFAULT_SERVER = '0.0.0.0':允许外部设备访问DEFAULT_SERVER_PORT = 5050:固定测试端口DATA_DIR:把测试数据目录放到项目内,方便隔离MASTER_PASSWORD_REQUIRED = False:测试时减少主密码弹窗干扰ENHANCED_COOKIE_PROTECTION = False:降低跨设备测试时 cookie 保护导致的干扰UPGRADE_CHECK_ENABLED = False:避免启动后访问外部版本检查接口造成日志超时
pgAdmin 前端资源需要提前构建。之前页面一直显示等待中,其中一个关键原因就是服务端返回的页面引用了:
/static/js/generated/...
但是这些 generated 静态资源没有构建出来,导致浏览器不断请求 404。
修复方式是在 web/ 目录下重新安装并构建前端资源:
cd ~/XM/pgadmin4-master/web
corepack yarn install
NODE_ENV=production NODE_OPTIONS=--max-old-space-size=3072 corepack yarn run webpacker
然后回到项目根目录启动 pgAdmin 服务:
cd ~/XM/pgadmin4-master
.pgadmin-test-venv/bin/python web/pgAdmin4.py
本次测试账号:
test@example.com
testpass
服务启动后,Mac 本机可访问:
http://127.0.0.1:5050
如果使用同一局域网测试,也可以让鸿蒙 PC 访问:
http://<Mac 局域网 IP>:5050
但本次最终采用的是 USB reverse 方式,稳定性更好,不依赖 Wi-Fi IP 是否变化。
六、构建、安装和 USB reverse
构建 HAP 的命令:
cd ~/XM/pgadmin4-master
PGADMIN_OHOS_EXTERNAL_SERVER_URL=http://127.0.0.1:5050 make ohos-hap
构建成功后会输出 HAP 文件,本次最终安装的是:
ohos_hap/electron/build/default/outputs/default/electron-default-signed.hap
安装到 HarmonyOS PC 设备:
/Applications/DevEco-Studio.app/Contents/sdk/default/openharmony/toolchains/hdc \
-t 3QC0124C20001268 \
install -r ohos_hap/electron/build/default/outputs/default/electron-default-signed.hap
建立 USB reverse:
/Applications/DevEco-Studio.app/Contents/sdk/default/openharmony/toolchains/hdc \
-t 3QC0124C20001268 \
rport tcp:5050 tcp:5050
如果看到类似下面的提示:
[Fail]TCP Port listen failed at 5050
不一定是失败,也可能是映射已经存在。可以直接在鸿蒙设备侧验证:
/Applications/DevEco-Studio.app/Contents/sdk/default/openharmony/toolchains/hdc \
-t 3QC0124C20001268 \
shell wget -O - http://127.0.0.1:5050/login
只要能返回 pgAdmin 登录页 HTML,就说明鸿蒙设备访问 127.0.0.1:5050 已经能打到 Mac 侧服务。

七、白屏问题定位和修复
最开始 HAP 装到鸿蒙 PC 后,出现过白屏和启动异常。这里的问题不是单一原因,而是几处 Electron runtime 差异叠加出来的。
7.1 GPU 禁用时机导致主进程异常
pgAdmin runtime 原来会调用:
app.disableHardwareAcceleration()
在 OpenHarmony Electron runtime 中,应用可能已经进入 ready 状态后才执行到这段逻辑。如果此时继续调用,就可能触发异常,导致主进程启动链路中断。
修复后改成先追加命令行开关:
app.commandLine.appendSwitch('disable-gpu');
app.commandLine.appendSwitch('disable-gpu-compositing');
如果 app.isReady() 已经为 true,就只打印信息,不再强行调用 app.disableHardwareAcceleration():
console.info('Skipping app.disableHardwareAcceleration(); Electron app is already ready.');
7.2 菜单数据未到导致 map 报错
日志里还出现过:
TypeError: Cannot read properties of undefined (reading 'map')
问题点在:
runtime/src/js/menu.js
pgAdmin 的菜单数据来自 renderer 侧。如果 refreshMenus() 执行时 renderer 还没有发送完整菜单数据,原逻辑直接对空值执行 map,就会让主进程报错。
修复思路是对菜单数据做空保护:
if (!Array.isArray(cachedMenus)) {
return;
}
同时 bindMenuClicks() 里也对 submenu 做数组判断,菜单为空时退回最小可用菜单。这样即使 renderer 菜单数据还没到,主窗口也不会因为菜单刷新而崩。
7.3 外部服务加载失败时没有稳定兜底
pgAdmin 在普通桌面环境下默认自己拉起 Python 服务。但在 OpenHarmony 模式下,我们希望优先加载外部 pgAdmin Server。
因此 runtime/src/js/pgadmin.js 做了几处调整:
- OpenHarmony 下默认进入 external server mode
- 优先复用主窗口,不再依赖额外小窗口承载配置页
- 加入
did-fail-load监听 - 加入 15 秒加载超时
- 加载失败时回到 Server URL 配置页
- 配置页通过
window.pgadminSetExternalServerStatus显示具体失败原因
对应配置页在:
runtime/src/html/external_server.html
其中暴露了状态更新函数:
window.pgadminSetExternalServerStatus = setStatus;
这样一来,如果 HAP 里配置了错误的旧 IP,例如:
http://192.168.0.76:5050/
页面不会一直白屏,而是能退回 URL 配置页面,让用户重新填写可访问地址。
八、一直显示等待中的问题
白屏修完之后,又遇到过页面一直显示“等待中”的问题。
这次的核心不是 HAP 没启动,而是 pgAdmin Web 页面加载后,前端静态资源没有完整返回。服务端页面里引用了 generated bundle:
/static/js/generated/...
但本地 web 目录没有构建出对应产物,导致 HarmonyOS PC 上的页面一直等不到完整前端资源。这个问题在 Mac 浏览器里直接打开 http://127.0.0.1:5050 也能发现,只是放到 HAP 里表现为一直等待。
处理方式就是重新构建 pgAdmin Web 前端:
cd ~/XM/pgadmin4-master/web
corepack yarn install
NODE_ENV=production NODE_OPTIONS=--max-old-space-size=3072 corepack yarn run webpacker
构建完成后,重启 Mac 侧 pgAdmin Server,再重新打开鸿蒙 PC 上的 HAP。此时页面就可以进入 pgAdmin 登录页。
这个问题也说明,适配 Electron HAP 时不要只盯鸿蒙侧。如果页面卡在等待中,要同时看三边:
- HAP 主进程日志
- HarmonyOS PC 到服务端的网络连通性
- Mac 上 pgAdmin Server 自己是否能完整返回前端资源
九、鸿蒙 PC 上登录 pgAdmin
在 Mac 侧服务启动、USB reverse 建立、HAP 安装完成后,打开 HarmonyOS PC 上的 pgAdmin 应用。
如果 HAP 构建时已经写入:
PGADMIN_OHOS_EXTERNAL_SERVER_URL=http://127.0.0.1:5050
应用启动后会直接加载:
http://127.0.0.1:5050
因为 USB reverse 已经建立,这个地址实际会访问 Mac 上的 pgAdmin Server。
登录信息:
Email: test@example.com
Password: testpass
登录成功后,可以看到 pgAdmin 的 Browser 树、Dashboard、菜单和主体页面正常显示。

十、连接 PostgreSQL 测试库
为了确认不是“只打开了页面”,还需要真的连一次 PostgreSQL。
本次使用了一个本地 Docker PostgreSQL 测试容器:
容器名:nexent-postgresql
端口:5434 -> 5432
数据库:nexent
用户名:root
密码:nexent@4321
pgAdmin 中导入的测试服务器配置文件:
~/XM/pgadmin4-master/.ohos_build/pgadmin-test-servers.json
导入命令:
cd ~/XM/pgadmin4-master
.pgadmin-test-venv/bin/python web/setup.py load-servers \
~/XM/pgadmin4-master/.ohos_build/pgadmin-test-servers.json \
--user test@example.com \
--sqlite-path ~/XM/pgadmin4-master/.pgadmin-test-data/pgadmin4.db
导入后 pgAdmin 左侧对象树中可以看到:
local-test-nexent
连接成功后,可以展开:
Databases
Login/Group Roles
Tablespaces
也可以执行测试 SQL:
select * from codex_pgadmin_ohos_test;
测试数据中包含:
ohos-pgadmin-test
到这一步,说明 HarmonyOS PC 上运行的 pgAdmin HAP 已经不只是“能打开”,而是可以通过 Mac 侧 pgAdmin Server 实际完成数据库管理链路。

十一、这次适配涉及的关键文件
本次适配核心修改和新增文件可以按作用分成几类。
第一类是 OpenHarmony 平台识别:
runtime/src/js/platform.js
它负责判断当前是否是 OpenHarmony 环境、是否禁用 GPU、是否读取外部服务地址,以及是否显式启用本地 Python 模式。
第二类是 pgAdmin Electron 主进程:
runtime/src/js/pgadmin.js
主要改动包括:
- OpenHarmony 下默认进入 external server mode
- 支持通过
PGADMIN_EXTERNAL_SERVER_URL加载外部 pgAdmin Server - 加载失败时回退到 URL 配置页
- 复用主窗口承载配置页和 pgAdmin 页面
- 避免 ready 后继续调用
app.disableHardwareAcceleration() - OpenHarmony 下不启动自动更新流程
第三类是菜单兼容:
runtime/src/js/menu.js
主要修复菜单数据为空时的崩溃问题。renderer 侧菜单还没发过来时,主进程不再对 undefined 调用 map,并提供最小菜单兜底。
第四类是外部服务配置页:
runtime/src/html/external_server.html
这个页面用于在没有内置 Python 服务时,让用户输入已有 pgAdmin Server 地址。加载失败时也可以把错误原因显示到页面底部。
第五类是 HAP 构建脚本:
pkg/ohos/build-package.mjs
pkg/ohos/build-hap.mjs
它们把 pgAdmin runtime 同步到 HAP 的 resources/app,再调用 Hvigor 生成 HAP。
第六类是 OpenHarmony HAP 工程:
ohos_hap/
这里包含 Electron 模块、web_engine 模块、OpenHarmony 配置、权限、native runtime 库和最终构建产物。
十二、最终验证结果
最终验证结果如下:
- HAP 可以成功构建
- HAP 可以安装到 HarmonyOS PC
- 应用启动后不再白屏
- 旧 IP 或服务不可达时可以回到 Server URL 配置页
- USB reverse 到
127.0.0.1:5050可用 - pgAdmin 登录页正常显示
test@example.com / testpass可以登录- 可以展开
local-test-nexent - 可以查看
Databases、Login/Group Roles、Tablespaces - Dashboard 页面和图表可以正常显示
- PostgreSQL 测试表
codex_pgadmin_ohos_test可以查询
这说明本次适配已经达到“用户可以使用”的第一阶段目标。
十三、总结
pgAdmin4 的鸿蒙 PC 适配和普通 Electron 应用不太一样。普通 Electron 应用通常只需要处理主进程、renderer、资源路径和少量 API 兼容。但 pgAdmin4 背后还有 Python Flask 服务、前端构建产物、SQLite 用户数据、PostgreSQL 连接配置和数据库客户端生态。
所以这次没有直接把问题扩大成“在鸿蒙 HAP 中完整内置 Python 桌面版 pgAdmin”,而是先做了一个可运行、可登录、可连接数据库的 OpenHarmony Electron HAP 版本。
这条路径的关键是:
- Electron HAP 负责承载 pgAdmin runtime
- Mac 负责启动 pgAdmin Web 服务
- 通过 USB reverse 或局域网让鸿蒙 PC 访问服务
- pgAdmin Server 再连接真实 PostgreSQL
在这个基础上,下一阶段如果继续做完全离线版,就可以再攻本地 Python runtime、Python 依赖、libpq 和 PostgreSQL 工具链。但从用户可用角度看,目前这个版本已经完成了从启动、登录到数据库连接验证的完整闭环。
更多推荐




所有评论(0)