在 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 位注册表项。