作为VS安装程序自定义动作运行PowerShell脚本时无法找到注册表路径
问题描述
我编写了一个用于读写注册表的PowerShell脚本,手动运行、通过命令行调用、使用ps2exe转换为.exe文件运行时均正常工作。但当我使用MS Visual Studio Installer Projects将其打包到安装程序中,作为Custom Actions/Commit/script.exe运行时,却无法找到注册表键。
脚本片段:
## initializing new variables $req_path = Get-Item -Path "HKCU:\SOFTWARE\Microsoft\Office\16.0\Excel\Options" | Select-Object -ExpandProperty Property echo $req_path
报错信息:
ERROR: Get-Item : Cannot find path
'HKCU:\SOFTWARE\Microsoft\Office\16.0\Excel\Options' because it does not exist.
我也尝试了如下写法,但仍无效:
$req_path = Get-Item -Path Registry::HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\16.0\Excel\Options | Select-Object -ExpandProperty Property
补充信息:
[Environment]::Is64BitProcess返回TrueWhoAmI返回nt authority\system
解决方案
核心原因
安装程序的自定义动作以NT AUTHORITY\SYSTEM身份运行,此时HKCU指向的是系统账户的注册表 hive,而非当前登录用户的。你手动运行脚本时使用的是自己的用户账户,对应的HKCU才包含Office相关注册表项,两者属于完全不同的注册表分支。
具体解决方法
方法1:加载当前登录用户的注册表 hive
在系统账户下访问当前登录用户的HKCU,需要先加载用户的注册表文件:
- 获取当前登录用户的SID:
$currentUser = Get-WmiObject -Class Win32_ComputerSystem | Select-Object -ExpandProperty UserName $userSID = (New-Object System.Security.Principal.NTAccount($currentUser)).Translate([System.Security.Principal.SecurityIdentifier]).Value
- 加载用户的
NTUSER.DAT到临时注册表路径:
reg load HKU\TempUser "C:\Users\$($currentUser.Split('\')[1])\NTUSER.DAT"
- 访问临时加载的注册表项:
$req_path = Get-Item -Path "HKU:\TempUser\SOFTWARE\Microsoft\Office\16.0\Excel\Options" | Select-Object -ExpandProperty Property
- 操作完成后卸载临时hive:
reg unload HKU\TempUser
方法2:修改自定义动作的运行身份
在Visual Studio Installer Projects中,调整自定义动作的属性:
- 将InstallerClass设为
False - 将Execute属性改为
deferred - 勾选Impersonate选项
这样自定义动作会以当前登录用户的身份运行,而非系统账户,就能正常访问该用户的HKCU注册表项。
注意事项
- 方法1需确保用户的
NTUSER.DAT未被锁定,已登录用户的该文件通常可正常加载,无人值守安装场景需额外验证。 - 方法2仅适用于允许以当前用户身份执行的场景,若安装程序必须依赖系统权限完成其他操作,需根据实际需求选择方案。
内容的提问来源于stack exchange,提问作者M--
相关产品推荐
相关产品推荐

