我需要从这两个位置远程收集有关设备上已安装软件的数据:
HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\
HKLM:\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\
为此,我正在使用 WMI 类
StdRegProv
。
收集数据的应用程序需要是 32 位的。
问题是我只收到来自
Wow6432Node
的数据,并且数据增加了一倍。例如。如果 64 位部分有 3 条记录,32 位部分有 5 条记录,我将总共收到 10 条记录(5 条唯一)。
如何阻止 WMI 进行重定向?
VB 不是 C#,但这对我有用,并且无论您的应用程序是作为 32 位进程还是 64 位进程运行,都可以进行编码。神奇的地方是第 8 行周围的 IF 语句 - 如果您的进程是 32 位进程,IntPtr.Size 只会是 4。
Public Function GetSettingEx(PredefinedKey As PredefinedKeyEnum, Section As String, Key As String, Default_Renamed As String, sComputerName As String, Optional b64Bit As Boolean = False) As String
Try
Dim options As New ConnectionOptions()
options.Impersonation = ImpersonationLevel.Impersonate
Dim scope As New ManagementScope("\\" & sComputerName & "\root\default", options)
If IntPtr.Size = 4 Then
scope.Options.Context.Add("__ProviderArchitecture", 64)
scope.Options.Context.Add("__RequiredArchitecture", True)
End If
scope.Connect()
Dim regclass As New ManagementClass(scope, New ManagementPath("StdRegProv"), Nothing)
Dim hDefKey As UInteger = MapPredefinedKeyToWMI(PredefinedKey)
Dim methodParams As ManagementBaseObject = regclass.GetMethodParameters("EnumValues")
methodParams("hDefKey") = hDefKey
methodParams("sSubKeyName") = Section
Dim outParams As ManagementBaseObject = regclass.InvokeMethod("EnumValues", methodParams, Nothing)
If CUInt(outParams("ReturnValue")) = 0 Then
Dim valueNames As String() = DirectCast(outParams.Properties("sNames").Value, String())
Dim valueTypes As Integer() = DirectCast(outParams.Properties("Types").Value, Integer())
If valueNames Is Nothing Then
Return ""
End If
For i As Integer = 0 To valueNames.Length - 1
Dim name As String = valueNames(i)
If name = Key Then
Dim regtype As RegistryTypes = CType(valueTypes(i), RegistryTypes)
Select Case regtype
Case RegistryTypes.REG_SZ, RegistryTypes.REG_EXPAND_SZ
Dim methodParamssz As ManagementBaseObject = regclass.GetMethodParameters("GetStringValue")
methodParamssz("hDefKey") = hDefKey
methodParamssz("sSubKeyName") = Section
methodParamssz("sValueName") = Key
Dim outParamssz As ManagementBaseObject = regclass.InvokeMethod("GetStringValue", methodParamssz, Nothing)
Dim value As Object = outParamssz.Properties("sValue").Value
Return CStr(value)
Case RegistryTypes.REG_MULTI_SZ
Dim methodParamssz As ManagementBaseObject = regclass.GetMethodParameters("GetMultiStringValue")
methodParamssz("hDefKey") = hDefKey
methodParamssz("sSubKeyName") = Section
methodParamssz("sValueName") = Key
Dim outParamssz As ManagementBaseObject = regclass.InvokeMethod("GetMultiStringValue", methodParamssz, Nothing)
Dim value As Object = outParamssz.Properties("sValue").Value
Return String.Join(",", DirectCast(value, String()))
Case RegistryTypes.REG_DWORD
Dim methodParamsdword As ManagementBaseObject = regclass.GetMethodParameters("GetDWORDValue")
methodParamsdword("hDefKey") = hDefKey
methodParamsdword("sSubKeyName") = Section
methodParamsdword("sValueName") = Key
Dim outParamsdword As ManagementBaseObject = regclass.InvokeMethod("GetDWORDValue", methodParamsdword, Nothing)
Dim value As Object = outParamsdword.Properties("uValue").Value
Return CStr(value)
Case RegistryTypes.REG_QWORD
Dim methodParamsqword As ManagementBaseObject = regclass.GetMethodParameters("GetQWORDValue")
methodParamsqword("hDefKey") = hDefKey
methodParamsqword("sSubKeyName") = Section
methodParamsqword("sValueName") = Key
Dim outParamsqword As ManagementBaseObject = regclass.InvokeMethod("GetQWORDValue", methodParamsqword, Nothing)
Dim value As Object = outParamsqword.Properties("uValue").Value
Return CStr(value)
Case RegistryTypes.REG_BINARY
Dim methodParamsbinary As ManagementBaseObject = regclass.GetMethodParameters("GetBinaryValue")
methodParamsbinary("hDefKey") = hDefKey
methodParamsbinary("sSubKeyName") = Section
methodParamsbinary("sValueName") = Key
Dim outParamsbinary As ManagementBaseObject = regclass.InvokeMethod("GetBinaryValue", methodParamsbinary, Nothing)
Dim value As Object = outParamsbinary.Properties("uValue").Value
Return BitConverter.ToString(DirectCast(value, Byte()))
Case Else
Throw New Exception("Unknown registry type : " & regtype.ToString)
End Select
End If
Next
End If
Return Default_Renamed
Catch ex As Exception
Return Default_Renamed
End Try
End Function
Public Enum PredefinedKeyEnum
HKEY_CLASSES_ROOT = &H80000000
HKEY_CURRENT_USER = &H80000001
HKEY_LOCAL_MACHINE = &H80000002
HKEY_USERS = &H80000003
HKEY_PERFORMANCE_DATA = &H80000004
HKEY_CURRENT_CONFIG = &H80000005
HKEY_DYN_DATA = &H80000006
End Enum
Private Function MapPredefinedKeyToWMI(PredefinedKey As PredefinedKeyEnum) As UInteger
Dim ret As UInteger
Select Case PredefinedKey
Case PredefinedKeyEnum.HKEY_CLASSES_ROOT
ret = 2147483648 ' &H80000000
Case PredefinedKeyEnum.HKEY_CURRENT_USER
ret = 2147483649 ' &H80000001
Case PredefinedKeyEnum.HKEY_LOCAL_MACHINE
ret = 2147483650 ' &H80000002
Case PredefinedKeyEnum.HKEY_USERS
ret = 2147483651 ' &H80000003
Case PredefinedKeyEnum.HKEY_PERFORMANCE_DATA
ret = 2147483652 ' &H80000004
Case PredefinedKeyEnum.HKEY_CURRENT_CONFIG
ret = 2147483653 ' &H80000005
Case PredefinedKeyEnum.HKEY_DYN_DATA
ret = 2147483654 ' &H80000006
Case Else
Throw New ArgumentException("Invalid predefinedKey")
End Select
Return ret
End Function