Windows10如何从注册表提取Microsoft.Windows.Photos的安装路径?
针对需要复用现有Win32注册表API逻辑、无需引入新运行时依赖的遗留应用场景,面对Microsoft.Windows.Photos这类系统预配(Provisioned)MSIX/UWP应用,完全不需要改造现有已稳定运行的注册表读写逻辑,仅需要定位正确的系统注册表分支即可实现路径提取,核心逻辑如下:
首先排除无效的常规注册表路径
这类预打包应用不会向传统程序的注册表分支写入可执行路径,在以下路径遍历是完全无效的:
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall下的传统程序卸载项HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths下的传统应用路径注册项
上述路径是传统Win32安装程序的标准写入位置,MSIX打包的预配应用完全不会遵循这个写入规则,遍历这些位置只会浪费性能,甚至误读其他同名Win32程序的路径。
最优的注册表锚点路径
系统预配应用的包元数据全部存储在系统级注册表分支,对所有Win10版本(1507到22H2)全兼容,目标根路径为:HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Appx\AppxAllUserStore\ProvisionedPackages
这个分支下的每个子项对应该设备上所有预装、预配置的应用包,子项名称是动态变化的完整包名(格式为应用包名_版本号_架构_语言_发布者ID,比如Microsoft.Windows.Photos_2023.23110.2271.0_neutral_~_8wekyb3d8bbwe),不需要硬编码固定子项名,遍历匹配前缀即可定位目标。
适配遗留代码的提取步骤
完全复用现有已实现的注册表遍历、值读取API逻辑,仅需要调整遍历的根路径和匹配规则:
- 遍历上述ProvisionedPackages分支下的所有子项,匹配子项名称以
Microsoft.Windows.Photos_为前缀的目标包项 - 对匹配到的子项,直接读取其下名为
Path的字符串值,该值由系统自动维护,格式为应用安装根目录(类似C:\Program Files\WindowsApps\Microsoft.Windows.Photos_xxx_neutral_xxx_8wekyb3d8bbwe)。系统每次完成Photos应用的版本升级,都会自动更新这个值,不需要手动适配版本号变化 - 拼接得到完整可执行路径:Photos的可执行文件名固定为
Microsoft.Windows.Photos.exe,将读取到的Path值和该文件名用反斜杠拼接,即可得到完整安装路径
针对32位遗留应用跑在64位Win10上的高频踩坑点:打开注册表键时必须带上
KEY_WOW64_64KEY访问标志,否则会被系统重定向到32位注册表的虚拟化视图,读到空值。核心打开键的API调用参考:RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Appx\\AppxAllUserStore\\ProvisionedPackages", 0, KEY_READ | KEY_WOW64_64KEY, &hKey)
方案选型的合理性说明
选择这个方案是所有可选实现路径中改造成本最低的:
- 完全复用现有已稳定运行的注册表代码框架,不需要引入WinRT的PackageManager类API,不需要为遗留应用适配C++/WinRT、COM组件调用逻辑
- 不受当前登录用户的应用安装状态影响,路径来源是系统级预配存储,哪怕新用户还没初始化Photos应用,也能稳定读到路径,适配遗留应用可能在系统服务、SYSTEM权限上下文运行的场景
- 全Win10版本兼容,从最早的Win10 1507版本到最新的22H2版本,该注册表分支和值的结构没有变化,不需要为不同系统版本做额外分支判断
内容的提问来源于stack exchange,提问作者DigviJay Patil

