Files
curios/docs/research/harmony-device-management.md
T

269 lines
33 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Harmony Connector 手机管理能力调研
调研日期:2026-09-10。承接 [USB 文件传输调研](harmony-connector.md),评估 Harmony Connector 从文件工具扩展为手机助手。以调研时的最新官方文档设计能力,不以 HarmonyOS 6 为硬上限;HUAWEI Pura 70 Ultra 是待验收设备,不能凭系统名称或文档命令表宣称真机已支持。
本文只做资料核查和本机工具定位,没有连接手机、安装应用、读取手机数据或改变设备状态。华为商业 HarmonyOS 文档与 OpenHarmony 开源资料分别标注。后者能证明对应源码/命令契约,不能直接证明商业固件的编译选项、授权策略与运行行为。
## 结论与实现优先级
建议保留 MTP 用户文件通道,并增加可选的本机官方 HDC 通道。HDC 支持 Mac,适合应用管理、调试文件和诊断;华为要求先开启并授权 USB/无线调试。普通文件传输不应因为新增管理能力而强制进入开发者模式。[华为 HDC](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/hdc)、[华为开发者选项](https://developer.huawei.com/consumer/cn/doc/HarmonyOS-Guides/ide-developer-mode)、[华为 USB 文件传输](https://consumer.huawei.com/cn/support/content/zh-cn16090699/)
以下优先级是本项目的工程建议,表示可实现范围,尚非真机验收结果:
| 优先级 | 功能 | 启用条件与产品表达 |
| --- | --- | --- |
| P0 | HDC 工具选择、版本和连接状态;设备基本信息 | 找到可运行工具,用户选择目标,授权成功;失败分清工具缺失、未授权、离线、命令不支持。 |
| P0 | 应用列表、应用详情、签名 HAP 安装、单应用卸载 | 包管理命令可用;安装预览包信息和覆盖影响;卸载显示具体包和数据损失。 |
| P0 | 日志快照、系统报告导出 | 用户触发,限时/限量,保存到用户选择的位置。 |
| P1 | 截图、应用启动、强制停止 | 先探测设备工具和真实组件;动作只针对用户选定对象。 |
| P1 | 调试应用数据导出;导出本机已有的安装包 | 沙箱导出逐应用检查调试签名与权限;安装包归档只处理用户拥有的原包,不等同从设备提取所有应用。 |
| P1 | 用户文件备份任务 | 明确选择范围、清单、校验和、失败项;仅称“所选文件备份”。 |
| P2 | 调试应用数据恢复、无线调试、实时日志/进程、UI 控制 | 探测成功后开放;恢复/控制/无线切换属于改变设备状态的动作。 |
| 暂不承诺 | 全机镜像、所有第三方应用数据备份、联系人/短信数据库直接读写、任意已安装应用导出并可恢复 | 未找到面向普通第三方 macOS 助手的官方公共接口;不能由 MTP 或 HDC shell 推导得到。 |
## 工具获取、发现和授权
华为官方获取路径为 DevEco Studio 所带 SDK,或 Command Line Tools 的 SDK;macOS 下典型位置为 `DevEco-Studio.app/Contents/sdk/default/openharmony/toolchains/hdc`。独立运行还需保留相邻 `libusb_shared` 依赖。这说明可以使用已安装的官方工具,不能据此推断可以重新打包分发华为整个 SDK。[华为 HDC 环境准备](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/hdc)、[官方工具下载入口](https://developer.huawei.com/consumer/cn/download/)
实现建议:先读用户保存的绝对路径,再查应用自身继承的 `PATH`,最后检查 `/Applications`、`~/Applications` 的 DevEco Studio 应用包及用户选定的 Command Line Tools 目录。解析软链接,验证是文件且可执行,显示最终路径。不要全盘扫描、执行下载来的未知工具或自动修改 shell 配置;GUI 的 PATH 不一定与交互终端相同。
本次本机只读发现:`PATH` 中无 `hdc`;在 `/Applications`、`~/Applications` 和存在的 `~/Library/OpenHarmony`、`~/Library/Huawei`、`~/Library/DevEcoStudio`、`~/ohos-sdk` 范围未找到候选工具。这不是“整台电脑绝无 HDC”的结论。没有安装 SDK,也没有执行设备命令。
首次开启开发者选项与随后打开调试开关是不同步骤:华为手机/平板指引要求在设备名称页连续点击软件版本七次,确认并按需输入 PIN,首次开启可能触发重启。之后 USB/无线调试需在手机确认计算机授权。插件应引导用户操作设备,不绕过锁屏、信任弹窗、企业调试管控。[华为开发者选项](https://developer.huawei.com/consumer/cn/doc/HarmonyOS-Guides/ide-developer-mode)
OpenHarmony HDC 仓库采用 Apache-2.0。若未来需要随插件交付 HDC,可评估从确切开源提交自行构建并保留许可证、版权与依赖声明;商业 Huawei 下载包的分发权需核对其实际许可,本次未确认该授权。不能把仓库许可扩展至 SDK 的其他组件或使用华为商标暗示官方产品。[OpenHarmony HDC LICENSE](https://github.com/openharmony/developtools_hdc/blob/e93f663afa159d3e601cad1e1869d70326731af6/LICENSE)
## CLI 调用契约
以下表格中 `key` 是用户选定的 `connect-key`,`bundle`/`ability`/`module` 来自设备已返回且验证过的数据;`local` 是用户选择的绝对本地路径。数组是传给 `Command::new(hdc).args(...)` 的 argv,省略可执行文件本身。带尖括号的值只作占位,不能原样执行。
宿主不要使用 `sh -c` 拼接 HDC 命令。`hdc shell` 的最后一个参数仍会由设备 shell 解释,必须用固定模板与严格参数验证/单引号转义;宿主 argv 安全不等于远端 shell 安全。文件名、应用名和设备返回内容都不是可信 shell 代码。
### 只读探测与设备信息
| 功能 | argv | 证据与处理 |
| --- | --- | --- |
| 客户端版本 | `["-v"]` | 解析 `Ver:` 字段,保留未知版本原文。 |
| 客户端/服务端版本 | `["checkserver"]` | 记录两端版本,不能认为刚选择的二进制已经替换后台旧服务。 |
| 设备状态 | `["list", "targets", "-v"]` | 识别 `USB/TCP` 和 `Unknown/Ready/Connected/Offline/Unauthorized`;`[Empty]` 表示没有目标。 |
| HDC 帮助 | `["-h", "verbose"]` | 作为本机命令存在性的证据。 |
| 包管理能力 | `["-t", key, "shell", "bm help"]` | 成功识别帮助内容后再开放相关操作。 |
| 组件管理能力 | `["-t", key, "shell", "aa help"]` | 不通过实际启动/停止应用来探测。 |
| 截图工具能力 | `["-t", key, "shell", "uitest help"]` | 要求返回可识别 `screenCap` 帮助。 |
| 日志工具能力 | `["-t", key, "shell", "hilog -h"]` | 确认 `-x` 可用。 |
| 基本设备信息 | `["-t", key, "shell", "hidumper -c base"]` | 华为文档展示 BuildId、ReleaseType、OsVersion、DeviceType 等字段。 |
| 参数读取 | `["-t", key, "shell", "param get <name>"]` | 单项读取,键需要固件实际返回/探测;未知键不应显示成空字符串的正常值。 |
HDC 命令和状态依据 [华为 HDC](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/hdc);设备信息依据 [华为 HiDumper](https://developer.huawei.com/consumer/cn/doc/doccenter-capabilities/hidumper);`param get` 语法依据 [OpenHarmony param 文档](https://github.com/openharmony/docs/blob/f41b9345badd47c7ab0c263344cd7f4b5a549afb/zh-cn/application-dev/tools/param-tool.md)。`hdc -t key shell hdcd -v` 是守护程序版本探测,不能当作手机完整系统版本。
实现应把“工具不存在”“没有授权”“权限不足”“输出无法识别”“版本不支持”与“数据为空”区分开。每个能力使用 `unknown / available / unavailable` 加原因;仅凭全局 HDC 连接成功不能一次性点亮所有管理功能。连接阶段不要执行 `kill -r`、`reconnect`、`tmode`、重启或任何包管理写操作。
### 应用列表、安装、卸载与运行
| 功能 | argv | 条件 |
| --- | --- | --- |
| 包名列表 | `["-t", key, "shell", "bm dump -a"]` | 华为官方 FAQ 直接采用该命令查询已安装应用。 |
| 包详情 | `["-t", key, "shell", "bm dump -n <bundle>"]` | 华为 HiDumper 指引用详情中的 `appProvisionType` 判断 debug。 |
| 调试包列表 | `["-t", key, "shell", "bm dump -g"]` | OpenHarmony 最新文档支持;需以本机帮助/实际输出确认。 |
| 应用显示名 | `["-t", key, "shell", "bm dump -n <bundle> -l"]` | OpenHarmony 文档标注 API 20 起;失败仍可显示包名。 |
| 安装签名 HAP | `["-t", key, "install", local]` | 本地绝对路径,成功后重新查询包版本。 |
| 单应用卸载 | `["-t", key, "uninstall", bundle]` | 指定包名;拒绝自动级联卸载依赖。 |
| 启动组件 | `["-t", key, "shell", "aa start -b <bundle> -a <ability> -m <module>"]` | 从详情找可启动、已导出的真实组件;不能硬编码所有应用都有 `EntryAbility`。 |
| 强制停止 | `["-t", key, "shell", "aa force-stop <bundle>"]` | 与正常退出不同,可能丢失尚未保存的工作。 |
查询依据:[华为应用市场错误排查](https://developer.huawei.com/consumer/en/doc/harmonyos-references/errorcode-appgallery)、[华为 HiDumper](https://developer.huawei.com/consumer/cn/doc/doccenter-capabilities/hidumper)。`bm` 详细参数与 user/root 限制依据 [OpenHarmony bm 文档](https://github.com/openharmony/docs/blob/f41b9345badd47c7ab0c263344cd7f4b5a549afb/zh-cn/application-dev/tools/bm-tool.md)。`aa` 的显式启动、exported 限制、强停和响应依据 [OpenHarmony aa 文档](https://github.com/openharmony/docs/blob/f41b9345badd47c7ab0c263344cd7f4b5a549afb/zh-cn/application-dev/tools/aa-tool.md);商业华为 HDC 将 aa 列为配套工具,但本次华为 aa 独立页面未成功抓取,故实际能力仍需设备探测。
安装不是“有 HAP 就能装”:华为要求真实设备使用签名包,自动签名会绑定调试设备信息。debug/release 签名、应用标识、版本和多模块一致性受安装器校验;不能把 OpenHarmony 的公开测试证书当作商业设备通用签名,也不能从 HDC 命令存在推导任意 release 包均可安装。[华为开发入门](https://developer.huawei.com/consumer/cn/develop-novice-guide/)、[华为自动签名](https://developer.huawei.com/consumer/cn/doc/HarmonyOS-Guides/ide-signing-auto)、[华为安装与更新一致性校验](https://developer.huawei.com/consumer/cn/doc/doccenter-getting-started/install-and-update-consistency-verification)
华为 HDC 说明 `install` 默认就是覆盖安装,省略 `-r` 不能防止覆盖;安装路径支持 HAP/应用内 HSP,APP 包从 API 22 起。`-w` 等组合参数有特殊解析约定,初版建议先只用必要参数。用户操作之前展示即将安装的应用与已装版本;签名冲突或系统拒绝时保留错误码,不能自动先卸载再安装。卸载共享库可能因其他应用依赖而被拒绝。[华为 HDC 安装说明](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/hdc)、[华为共享包依赖错误 9568312](https://developer.huawei.com/consumer/cn/doc/doccenter-dev-faq/faqs-technology-32)
包名清单是行文本,详情可能有标签/前缀加 JSON 内容,不能将所有 `bm` 命令输出当作同一个稳定 JSON API。建议仅接受明确命令对应的格式:列表验证包名,详情解析完整 JSON 对象并校验预期字段与查询包名;无法解析则显示原始诊断并禁用依赖该字段的操作。显示名不能作为包名、权限或可卸载性的替代。安装和卸载需同时判断进程结果、工具成功/失败信息及操作后的目标状态,不能只看是否含 `AppMod finish`。
### 截图、日志和系统报告
1. 探测 `uitest help` 后,为每次截图生成不可预测且只含安全字符的文件名。
2. 调用 `["-t", key, "shell", "uitest screenCap -p /data/local/tmp/curios-<nonce>.png"]`。
3. 调用 `["-t", key, "file", "recv", "/data/local/tmp/curios-<nonce>.png", localTemp]`。
4. 校验下载文件确实是可解码 PNG,再提交到用户目标位置。只删除本次创建的远端文件;失败时不要清理整个临时目录。
`uitest screenCap -p`、只能存到 `/data/local/tmp/` 的限制,以及 `-d` 多屏参数从 API 20 开始,均来自 [OpenHarmony UITest 官方文档](https://github.com/openharmony/docs/blob/f41b9345badd47c7ab0c263344cd7f4b5a549afb/zh-cn/application-dev/application-test/uitest-guidelines.md)。华为官方也提供 HiSmartPerf 的截图采集/文件导出流程,但本次没有将 `snapshot_display` 的商业固件可用性或任何投屏帧率作为已确认能力。[华为 HiSmartPerf](https://developer.huawei.com/consumer/cn/doc/doccenter-testing/smartperf-guidelines)
| 导出 | argv | 实现建议 |
| --- | --- | --- |
| 日志快照 | `["-t", key, "shell", "hilog -x"]` | `-x` 非阻塞读完退出,宿主将 stdout 写到独立临时文件。 |
| 实时日志 | `["-t", key, "shell", "hilog"]` | 持续读取,提供停止按钮和大小限制;不要视为普通短请求。 |
| 系统报告 | `["-t", key, "bugreport", localTemp]` | FILE 是本地路径;内容可能较多,预留更长但有限的超时。 |
| 已有落盘日志 | `["-t", key, "file", "recv", "/data/log/hilog", localDir]` | 只有权限与路径确认后才能导出,不需先开启新的落盘任务。 |
`hilog -x` 语义依据 [OpenHarmony HiLog](https://github.com/openharmony/docs/blob/f41b9345badd47c7ab0c263344cd7f4b5a549afb/zh-cn/application-dev/dfx/hilog.md);`bugreport` 与现有落盘日志路径依据 [华为 HDC](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/hdc)。日志与系统报告可能包含应用活动和设备标识;默认只本地保存,不自动上传。不要为普通日志导出自动执行清日志、关闭隐私过滤或开启持续日志落盘。
## 备份和恢复:需要分别命名的三种能力
### 用户文件副本
MTP 面向设备公开的存储对象。选择文件夹后递归复制、生成大小/校验和清单、记录失败项,是可以实现的“所选文件备份”;没有通过 MTP 暴露的沙箱、系统设置、账号和数据库不在范围内。图库模式限制沿用原调研,不能把普通文件夹可写推导为可任意恢复图库数据库。[libmtp 对象/存储 API](https://github.com/libmtp/libmtp/blob/v1.1.23/src/libmtp.h.in)、[华为 USB 文件传输](https://consumer.huawei.com/cn/support/content/zh-cn16090699/)
### 调试应用数据导出与导入
华为明确 `shell -b`、`file send/recv -b` 只用于“调试证书签名且已经在设备上启动”的应用;不是任意应用的沙箱读取入口。`-b` 从 API 15 引入。先查询 `appProvisionType`,再对具体目录进行只读访问探测,不应单凭包名出现在应用列表就启用备份。[华为 HDC 沙箱条件](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/hdc)、[华为 HiDumper 调试类型判定](https://developer.huawei.com/consumer/cn/doc/doccenter-capabilities/hidumper)
```text
查询指定调试应用目录:
["-t", key, "shell", "-b", bundle, "ls data/storage/el2/base/"]
导出用户选择的沙箱文件或目录:
["-t", key, "file", "recv", "-b", bundle, "<verified-remote-path>", "<new-local-directory>"]
向同一调试应用导入已选择的数据:
["-t", key, "file", "send", "-b", bundle, "<local-file>", "<verified-remote-path>"]
```
这些是官方 `-b` 文件操作语法,remote path 应在该应用实际可见的根目录内,不使用 `/data/app/...` 猜测另一个应用的路径,不接受越界 `..`。导出清单应记录设备/系统、包名、版本、签名类型、所选路径、时间、实际复制文件及校验结果。正在运行的应用可能继续写入数据库;原始文件副本不自动获得事务一致性,也不保证跨设备的密钥、登录状态或应用版本可恢复。建议界面名称为“导出调试应用数据”,完整备份成功必须有明确的范围与验证。
恢复是覆盖写入,不应在枚举或探测时尝试。只允许用户选择明确的备份和目标应用,核对包名/版本/范围,展示将修改的文件后执行。未经该应用可恢复性验证,不提供一键“全部应用恢复”。不要通过重新签名现有商业应用或卸载重装来制造沙箱访问权限。
### 官方系统备份
华为应用备份框架允许应用接入 `BackupExtensionAbility` 并声明可备份范围,但普通应用自身不能触发系统备份;触发功能面向系统应用。官方最新验证指引使用数据克隆,由新旧设备配对触发。应用可不接入,也可限制备份内容。因此额外装一个普通手机伴随应用,并不自然获得其他应用全部数据的备份权。[华为备份概述](https://developer.huawei.com/consumer/en/doc/harmonyos-guides-V13/app-file-backup-overview-V13)、[华为应用接入](https://developer.huawei.com/consumer/cn/doc/doccenter-capabilities/app-file-backup-extension)、[华为数据克隆验证](https://developer.huawei.com/consumer/cn/doc/doccenter-capabilities/app-file-backup-dataclone)
特别检查了 OpenHarmony `filemanagement_app_file_service` 提交 `589be5d84d3c23967be62ca7f0317690237a0041`:
- `backup_tool/BUILD.gn` 仅在 `build_variant == "root"` 编入真实操作,且 `install_enable = false`。
- 未定义 `BACKUP_TOOL_ENABLE` 时,`main()` 直接返回 0,不执行备份。
- 备份服务检查 BACKUP 权限;HAP 调用还检查系统应用身份,shell 调用亦受 UID 条件限制。
这是开源实现证据,不能证明商业设备使用完全相同实现;却直接说明“找到 backup_tool 且退出码为 0”不是备份成功证据。本轮不将该工具作为商业设备备份后端,也不自动尝试备份/恢复命令。[OpenHarmony 构建约束](https://github.com/openharmony/filemanagement_app_file_service/blob/589be5d84d3c23967be62ca7f0317690237a0041/tools/backup_tool/BUILD.gn)、[无操作入口](https://github.com/openharmony/filemanagement_app_file_service/blob/589be5d84d3c23967be62ca7f0317690237a0041/tools/backup_tool/src/main.cpp)、[服务权限检查](https://github.com/openharmony/filemanagement_app_file_service/blob/589be5d84d3c23967be62ca7f0317690237a0041/services/backup_sa/src/module_ipc/service.cpp)
## 与官方助手的能力对照
| 官方路线 | 已确认范围 | 对本插件的结论 |
| --- | --- | --- |
| HiSuite / 华为手机助手 | 当前官网针对 HarmonyOS 5+ 列出基础数据、部分第三方应用及数据、部分设置备份;受系统/应用兼容性限制。明确 5+ 暂不支持 macOS 连接。 | Windows 官方能力不等于 macOS 第三方插件可调用的协议/API。不能用旧 Android/HDB 教程保证原生鸿蒙兼容。 |
| 手机“备份和恢复 → 外部存储” | 官方 5+ 指引支持第三方应用和部分应用数据等,并需备份密码;范围以实际设备为准。 | 可以提供官方操作指引,或归档用户已经生成的备份文件;尚无公开证据支持插件在 Mac 直接触发/解密其备份。 |
| 数据克隆 | 最新开发者指引通过两台设备触发已接入应用的数据迁移验证。 | 是系统侧迁移流程,不是通用电脑备份 CLI。 |
| 华为分享 + 鸿蒙星河互联 | 官方提供与 Mac 的图片、视频、文档无线互传流程。 | 可链接官方方案;没有据此获得可嵌入分享 SDK、应用安装或全机备份能力。 |
分别依据:[华为 HiSuite 当前支持范围](https://consumer.huawei.com/cn/support/hisuite/)、[华为外部存储备份](https://consumer.huawei.com/cn/support/content/zh-cn16024725/)、[华为数据克隆验证](https://developer.huawei.com/consumer/cn/doc/doccenter-capabilities/app-file-backup-dataclone)、[华为与 Mac 互传](https://consumer.huawei.com/cn/support/content/zh-cn16093657/)。产品可以覆盖“文件、应用、设备、诊断、备份”模块;不同模块应展示实际通道与数据范围,不把官方系统级功能画成已经可执行的按钮。
## 无线与其他能力
用户先在手机开启无线调试,输入手机显示的 IP 和端口,然后调用 `["tconn", "<ip>:<port>"]`;断开用 `["tconn", "<ip>:<port>", "-remove"]`。官方仍将 TCP 调试标为测试场景。`tmode port` 会重启设备守护进程并断开会话,连接探测不应使用它。端口转发、重启、UI 输入可以作为后续显式操作,不默认启用。[华为 HDC 无线和连接管理](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/hdc)
最新文档版本提示用于解释能力差异,不作为 HarmonyOS 大版本硬编码:`-b` 与 API 15/HDC 3.1.0e 配套;API 20/HDC 3.2.0b 增加部分网络能力;APP 安装 API 22;安装自动授权 `-g` API 24;沙箱无命令交互式 shell、reconnect、子服务器等 API 26 新能力仍需两端支持。实现按本机帮助和设备实际结果逐项判定,不自动调用新命令来“修复”连接。[华为 HDC 版本表](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/hdc)
## 输出解析、操作风险与验收
建议为 HDC 建立独立执行适配器:固定可执行路径、每次携带目标、有限并发、逐设备串行写入、进程组取消、stdout/stderr 大小上限、操作超时。长日志和文件任务走流式输出,UI 接收结构化事件,不在前端解释 shell 字符串。不要为了隔离无条件另开 USB server,也不要在退出插件时杀掉用户 DevEco Studio 的共享 HDC 服务。
最小验收应覆盖可观察行为:
- 无工具、工具依赖缺失、未连接、拒绝授权、多设备、未知输出格式、版本不匹配,都不得显示假空列表或操作成功。
- 应用列表中中文显示名与包名分离;详情解析失败不影响其他条目;安装拒绝/签名冲突/包格式错误保留真实结果;成功安装/卸载后刷新验证。
- 签名 HAP 安装只能使用用户专门选取的测试包;卸载只能操作明确选择的应用。验证不得卸载用户日常应用来测试失败路径。
- 截图下载后能解码,报告文件非空且包含实际内容,日志导出有限且可取消;中断不会把临时文件报告为完成。
- 调试沙箱必须验证 release 应用被限制、debug 未启动的处理、权限失败、部分传输、中文/空格路径;导出实际文件校验和对应清单。恢复只在专门测试应用验证,并检查恢复后的应用行为。
- 系统备份无法实现时明确展示边界,不执行空壳 `backup_tool`,不以退出码 0、模拟输出、无设备测试或构建通过替代真机验收。
本调研最终产物仅为本文。文档命令来自第一方资料,设备兼容性仍需按实际固件验证;本机未找到 HDC 的范围见上文,未对手机执行任何命令。
## 补充:应用输出解析与真实入口选择
这一节按 2026-09-10 获取的 OpenHarmony 源码追踪输出生产链:Bundle Framework `e0b9be9be36186e040385895f7f764e6e111a809` 与 bm CLI `6b9b9ad316b764f472194a962081c0fb99c32fdf`。下面是**由源码生成规则还原、省略无关字段的代表样例**,不是 HUAWEI Pura 70 Ultra 的实测输出。商业设备返回新结构时应报告格式未知,不能假装已经得到相同数据。
### `bm dump -a` / `bm dump -g`
成功输出是按用户分组的纯文本,不是 JSON;当前 CLI 直接转发服务结果,没有额外 `all bundle names:` 标题。样例中的应用名是占位数据,缩进实际为制表符。服务支持多个用户段;CLI 默认查询当前用户,指定不活跃 `-u` 可能产生前置警告并退回当前用户。[BMS 列表生成](https://github.com/openharmony/bundlemanager_bundle_framework/blob/e0b9be9be36186e040385895f7f764e6e111a809/services/bundlemgr/src/bundle_mgr_host_impl.cpp#L2999)、[bm CLI 查询和转发](https://github.com/openharmony/bundlemanager_bundle_tool/blob/6b9b9ad316b764f472194a962081c0fb99c32fdf/frameworks/src/bundle_command.cpp#L1153)
```text
ID: 100:
com.example.notes
com.example.reader
```
解析建议:保留 userId 分组;只在已识别 `ID: <integer>:` 段内读取并验证包名;允许空段和空行;未知诊断行不能被当作应用。不要把任意含点字符串提取成包名,也不要把错误文本归一化成零应用。空结果或查询失败时,当前 CLI 会输出下面的错误,且 dump 分支仍可能返回成功退出码。[bm 空结果处理](https://github.com/openharmony/bundlemanager_bundle_tool/blob/6b9b9ad316b764f472194a962081c0fb99c32fdf/frameworks/src/bundle_command.cpp#L1246)、[缺包查询官方系统测试](https://github.com/openharmony/bundlemanager_bundle_tool/blob/6b9b9ad316b764f472194a962081c0fb99c32fdf/test/systemtest/bm/bm_command_dump_system_test.cpp#L106)
```text
error: failed to get information and the parameters may be wrong.
```
### `bm dump -n <bundle>` 的字段
服务先输出包名和冒号,再输出完整 JSON 对象。它显式移除顶层 `abilityInfos`,组件应从 `hapModuleInfos[].abilityInfos[]` 读取;不能把 manifest 的 `abilities` 字段直接当作 dump 格式。[BMS 详情组装](https://github.com/openharmony/bundlemanager_bundle_framework/blob/e0b9be9be36186e040385895f7f764e6e111a809/services/bundlemgr/src/bundle_mgr_host_impl.cpp#L3094)、[模块序列化](https://github.com/openharmony/bundlemanager_bundle_framework/blob/e0b9be9be36186e040385895f7f764e6e111a809/interfaces/inner_api/appexecfwk_base/src/hap_module_info.cpp#L927)
```text
com.example.notes:
{
"name": "com.example.notes",
"versionCode": 1000000,
"versionName": "1.0.0",
"entryModuleName": "entry",
"applicationInfo": {
"bundleName": "com.example.notes",
"appProvisionType": "debug"
},
"hapModuleInfos": [
{
"moduleName": "entry",
"mainAbility": "NotesAbility",
"mainElementName": "NotesAbility",
"isStageBasedModel": true,
"abilityInfos": [
{
"bundleName": "com.example.notes",
"moduleName": "entry",
"name": "NotesAbility",
"type": 1,
"visible": true,
"enabled": true,
"isStageBasedModel": true,
"isLauncherAbility": false,
"skills": [
{
"actions": ["ohos.want.action.home"],
"entities": ["entity.system.home"]
}
]
}
]
}
]
}
```
准确映射与限制:
| 需要的信息 | dump 字段与解释 |
| --- | --- |
| 应用身份/版本 | 顶层 `name`、`versionCode`、`versionName`;并校验 `applicationInfo.bundleName` 与查询目标一致。 |
| 调试签名 | `applicationInfo.appProvisionType`;调试值 `debug`,缺失是未知。 |
| 入口模块 | 顶层 `entryModuleName`;模块使用 `moduleName`,不是模块显示用的 `name`。 |
| 模块主组件 | `hapModuleInfos[].mainElementName`、`mainAbility`;当前 Stage 解析都来源于 manifest 的 `mainElement`。 |
| 实际组件 | `hapModuleInfos[].abilityInfos[]`,每项携带 `bundleName`、`moduleName`、`name`。 |
| 可见/导出状态 | dump 使用布尔 `visible`。Stage manifest 的 `exported` 写入内部 `visible`,且比旧 `visible` 配置优先;dump 不使用 `exported` 字段。 |
| UI 组件类型 | `type` 是数字枚举:`UNKNOWN=0`、`PAGE=1`、`SERVICE=2`、`DATA=3`、`FORM=4`、`EXTENSION=5`;Stage UIAbility 解析为 PAGE。 |
| 是否可用 | `enabled` 是布尔;显式 false 时不能作为启动候选。缺字段不应凭空生成 true。 |
| 桌面入口 skill | 同一项 `skills[]` 中,`actions` 含 `ohos.want.action.home` 或 `action.system.home`,且 `entities` 含 `entity.system.home`。 |
| `isLauncherAbility` | 不是普通应用“可从桌面启动”的通用标志。当前实现只在特殊 launcher entity、预装且系统应用等条件下设置。不能要求普通入口它必须为 true。 |
这些映射依据:[BundleInfo 序列化](https://github.com/openharmony/bundlemanager_bundle_framework/blob/e0b9be9be36186e040385895f7f764e6e111a809/interfaces/inner_api/appexecfwk_base/src/bundle_info.cpp#L898)、[ApplicationInfo 序列化](https://github.com/openharmony/bundlemanager_bundle_framework/blob/e0b9be9be36186e040385895f7f764e6e111a809/interfaces/inner_api/appexecfwk_base/src/application_info.cpp#L1064)、[组件 JSON 字段](https://github.com/openharmony/bundlemanager_bundle_framework/blob/e0b9be9be36186e040385895f7f764e6e111a809/interfaces/inner_api/appexecfwk_base/include/common_json_converter.h#L669)、[组件类型枚举](https://github.com/openharmony/bundlemanager_bundle_framework/blob/e0b9be9be36186e040385895f7f764e6e111a809/interfaces/inner_api/appexecfwk_base/include/ability_info.h#L57)、[exported 解析](https://github.com/openharmony/bundlemanager_bundle_framework/blob/e0b9be9be36186e040385895f7f764e6e111a809/services/bundlemgr/src/module_profile.cpp#L636)、[Stage 类型赋值](https://github.com/openharmony/bundlemanager_bundle_framework/blob/e0b9be9be36186e040385895f7f764e6e111a809/services/bundlemgr/src/module_profile.cpp#L2702)、[模块入口赋值](https://github.com/openharmony/bundlemanager_bundle_framework/blob/e0b9be9be36186e040385895f7f764e6e111a809/services/bundlemgr/src/inner_bundle_info.cpp#L1800)、[HOME skill 与 launcher 判定](https://github.com/openharmony/bundlemanager_bundle_framework/blob/e0b9be9be36186e040385895f7f764e6e111a809/services/bundlemgr/src/module_profile.cpp#L3005)、[HOME 字符串常量](https://github.com/openharmony/bundlemanager_bundle_framework/blob/e0b9be9be36186e040385895f7f764e6e111a809/interfaces/inner_api/appexecfwk_base/include/bundle_constants.h#L174)。
实现建议:从合法详情中选择 `type == 1 && visible == true`,排除明确禁用项,并校验组件包名/模块名;优先具有 HOME skill 的组件,再用入口模块和主组件字段消除歧义。没有唯一可确定入口时展示实际组件选择,不自动启动任意 exported 页面。`visible`、`type` 缺失时不能直接宣称可启动;旧格式适配应增加明确来源与 fixture。权限仍由系统决定,元数据筛选通过不保证启动一定成功。以上代表样例对应 argv 为 `["-t", key, "shell", "aa start -b com.example.notes -a NotesAbility -m entry"]`。
解析 JSON 时应先识别查询包名的前缀,再对完整对象解析;校验身份和字段类型,限制输入大小/嵌套深度。不要从错误文本中随意截取第一个到最后一个花括号,或在详情中递归搜同名 `name` 来猜应用身份。没有完整有效详情时保留应用条目和错误,禁用依赖组件/调试状态的操作。
## 补充:`hdc file recv -b` 目录层级
OpenHarmony HDC `e93f663afa159d3e601cad1e1869d70326731af6` 的收件端根据**传输开始时本地目标是否存在**决定是否保留源目录 basename;`-b` 在设备端解析沙箱路径,本地主机仍走同一文件接收逻辑。以下以已确认可读的 `data/storage/el2/base` 目录中存在 `files/a.txt` 为例。[HDC 源目录任务生成及沙箱处理](https://github.com/openharmony/developtools_hdc/blob/e93f663afa159d3e601cad1e1869d70326731af6/src/common/file.cpp#L266)、[接收端目标目录和文件名处理](https://github.com/openharmony/developtools_hdc/blob/e93f663afa159d3e601cad1e1869d70326731af6/src/common/transfer.cpp#L724)
| 调用前本地状态 | 接收目标 argv 最后一个参数 | 最终文件位置 |
| --- | --- | --- |
| `/exports/job` 已存在且为目录 | `/exports/job` | `/exports/job/base/files/a.txt` |
| `/exports/job` 不存在 | `/exports/job` | `/exports/job/files/a.txt` |
| `/exports/job` 已存在且为普通文件 | `/exports/job` | 目录模式报错,不能作为合法备份目标。 |
源路径加尾部 `/` 不构成“只复制内容”的开关;源 basename 提取前会去除尾部分隔符。目标不存在时接收器先建目标,再从相对任务路径剥掉第一层;目标已经存在则保留第一层。不要用 rsync 的尾斜杠规则推断 HDC。[basename 实现](https://github.com/openharmony/developtools_hdc/blob/e93f663afa159d3e601cad1e1869d70326731af6/src/common/base.cpp#L1823)、[CheckFilename 首层处理](https://github.com/openharmony/developtools_hdc/blob/e93f663afa159d3e601cad1e1869d70326731af6/src/common/transfer.cpp#L801)
建议先创建唯一、空的 staging 父目录,例如 `/exports/.curios-job-<nonce>`,再传 `["-t", key, "file", "recv", "-b", bundle, "data/storage/el2/base", "/exports/.curios-job-<nonce>"]`;验收期望位于 `staging/base/...` 的输出,记录 `remoteRoot` 与 `localRelativeRoot: "base"`。完成后按清单提交用户目标。恢复必须依清单映射,不能将整个 `base` 再送入设备已经存在的 `base`,制造 `base/base`。若想把目录内容直接放入目标,可使用尚不存在的目标路径,但实现必须控制初始状态,并在对应本机 HDC 版本做行为验收。
该源码递归任务以文件为单位,纯空源目录直接报 `Operation failed, because the source folder is empty.`;空子目录也不能按文件任务数量证明完整保留。不能把这类报错改写为完整备份成功。若产品承诺保留空目录,应另行枚举并记录空目录、处理权限失败,或将“不保留空目录”列入导出范围。源码不替代当前华为 SDK 二进制的行为测试。[目录遍历实现](https://github.com/openharmony/developtools_hdc/blob/e93f663afa159d3e601cad1e1869d70326731af6/src/common/transfer.cpp#L658)、[空目录官方测试](https://github.com/openharmony/developtools_hdc/blob/e93f663afa159d3e601cad1e1869d70326731af6/test/scripts/testModule/test_hdc_file.py#L502)