在 vbscript 中调用 EnumKey 作为安装程序查询 windows 注册表中的自定义操作会导致 wbemErrNotFound
Calling EnumKey in vbscript as custom action in an installer querying windows registry results in wbemErrNotFound
通过 here 中的示例,我创建了一个 vbscript,它使用 WMI 注册表对象来枚举注册表项“HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Components”上的子项。当我使用 WScript 测试它时,vbscript 运行良好并产生我需要的结果。
当我将 vbscript 作为自定义操作嵌入到安装程序中时,EnumKey 调用 returns 错误 wbemErrNotFound(2)。但是,如果我枚举其他一些键,它可能会 return 成功。是权限问题吗?我已经尝试 运行 提升权限的安装程序。我如何让它与安装程序一起工作?
为了演示问题,下面是我使用的 vbscript 的简化版本:
Const HKEY_LOCAL_MACHINE = &H80000002
Const KEY_ENUMERATE_SUB_KEYS = &H00000008
Function CountSubKeys(nHiveRoot, sKeyPath)
Const sComputer = "." ' Use . for current machine
Dim nRet
Dim nSum
MsgBox "EnumKey: " & sKeyPath, vbOkOnly, "CountSubKeys"
' Set oReg = GetObject( "winmgmts:{impersonationLevel=impersonate}!//" & sComputer & "/root/default:StdRegProv" )
Set oReg = GetObject( "winmgmts:{impersonationLevel=impersonate}!//" & sComputer & "/root/cimv2:StdRegProv" )
Dim bGranted
nRet = oReg.CheckAccess(nHiveRoot, sKeyPath, KEY_ENUMERATE_SUB_KEYS, bGranted)
If (nRet = 0) Then
If bGranted = True Then
MsgBox "Access to key: " & sKeyPath & " is granted", vbOkOnly, "CountSubKeys"
Else
MsgBox "Access to key: " & sKeyPath & " is denied", vbOkOnly, "CountSubKeys"
End If
Else
MsgBox "Failed to check key access: " & sKeyPath & ", nRet: " & nRet, vbOkOnly, "CountSubKeys"
End If
nRet = oReg.EnumKey(nHiveRoot, sKeyPath, arrSubKeys)
If (nRet = 0) Then
If isArray(arrSubKeys) Then
nSum = UBound(arrSubKeys) + 1
MsgBox "Number of sub keys: " & nSum, vbOkOnly, "CountSubKeys"
Else
MsgBox "EnumKey return no sub key on path" & sKeyPath, vbOkOnly, "CountSubKeys"
nSum = 0
End If
Else
MsgBox "Failed to enum key: " & sKeyPath & ", Err: " & nRet, vbOkOnly, "CountSubKeys"
nSum = -1
End If
CountSubKeys = nSum
End Function
Sub TestEnumKey()
Const sInstalledComponentKey = "SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Components\"
nCount = CountSubKeys(HKEY_LOCAL_MACHINE, sInstalledComponentKey)
MsgBox "nCount: " & nCount, vbOkOnly, "TestEnumKey"
End Sub
TestEnumKey()
自定义操作使用 Sub TestEnumKey() 作为 vbscrpt 的入口点。
该错误不是由注册表项的权限引起的。这是由于在 32 位脚本主机上访问 64 位注册表。
当我使用 WScript 测试 vbscript 时,它默认使用 64 位脚本主机并默认访问 64 位注册表并成功枚举子项。
我的安装程序是 32 位 msi,因此它的自定义操作调用 32 位脚本主机,它默认访问 32 位注册表,当然找不到 64 位注册表项。
通过 here 中的示例,我创建了一个 vbscript,它使用 WMI 注册表对象来枚举注册表项“HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Components”上的子项。当我使用 WScript 测试它时,vbscript 运行良好并产生我需要的结果。
当我将 vbscript 作为自定义操作嵌入到安装程序中时,EnumKey 调用 returns 错误 wbemErrNotFound(2)。但是,如果我枚举其他一些键,它可能会 return 成功。是权限问题吗?我已经尝试 运行 提升权限的安装程序。我如何让它与安装程序一起工作?
为了演示问题,下面是我使用的 vbscript 的简化版本:
Const HKEY_LOCAL_MACHINE = &H80000002
Const KEY_ENUMERATE_SUB_KEYS = &H00000008
Function CountSubKeys(nHiveRoot, sKeyPath)
Const sComputer = "." ' Use . for current machine
Dim nRet
Dim nSum
MsgBox "EnumKey: " & sKeyPath, vbOkOnly, "CountSubKeys"
' Set oReg = GetObject( "winmgmts:{impersonationLevel=impersonate}!//" & sComputer & "/root/default:StdRegProv" )
Set oReg = GetObject( "winmgmts:{impersonationLevel=impersonate}!//" & sComputer & "/root/cimv2:StdRegProv" )
Dim bGranted
nRet = oReg.CheckAccess(nHiveRoot, sKeyPath, KEY_ENUMERATE_SUB_KEYS, bGranted)
If (nRet = 0) Then
If bGranted = True Then
MsgBox "Access to key: " & sKeyPath & " is granted", vbOkOnly, "CountSubKeys"
Else
MsgBox "Access to key: " & sKeyPath & " is denied", vbOkOnly, "CountSubKeys"
End If
Else
MsgBox "Failed to check key access: " & sKeyPath & ", nRet: " & nRet, vbOkOnly, "CountSubKeys"
End If
nRet = oReg.EnumKey(nHiveRoot, sKeyPath, arrSubKeys)
If (nRet = 0) Then
If isArray(arrSubKeys) Then
nSum = UBound(arrSubKeys) + 1
MsgBox "Number of sub keys: " & nSum, vbOkOnly, "CountSubKeys"
Else
MsgBox "EnumKey return no sub key on path" & sKeyPath, vbOkOnly, "CountSubKeys"
nSum = 0
End If
Else
MsgBox "Failed to enum key: " & sKeyPath & ", Err: " & nRet, vbOkOnly, "CountSubKeys"
nSum = -1
End If
CountSubKeys = nSum
End Function
Sub TestEnumKey()
Const sInstalledComponentKey = "SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Components\"
nCount = CountSubKeys(HKEY_LOCAL_MACHINE, sInstalledComponentKey)
MsgBox "nCount: " & nCount, vbOkOnly, "TestEnumKey"
End Sub
TestEnumKey()
自定义操作使用 Sub TestEnumKey() 作为 vbscrpt 的入口点。
该错误不是由注册表项的权限引起的。这是由于在 32 位脚本主机上访问 64 位注册表。
当我使用 WScript 测试 vbscript 时,它默认使用 64 位脚本主机并默认访问 64 位注册表并成功枚举子项。
我的安装程序是 32 位 msi,因此它的自定义操作调用 32 位脚本主机,它默认访问 32 位注册表,当然找不到 64 位注册表项。