Member 13262965 Ответов: 2

Как я могу прочитать physicalhostname registrykey через WMI


Мне нужно прочитать
SOFTWARE\Microsoft\Virtual Machine\Guest\Parameters\PhysicalHostName
Раздел реестра для получения имени хоста виртуальной машины Hyper V.

Я могу подключиться и также получить много информации через wmi в других частях программы, но я спотыкаюсь, если дело доходит до чтения раздела реестра :(

Я знаю, что есть способ получить имена всех виртуальных машин через пространство имен/ virtualization/. Однако это не то, что мне нужно, так как я должен нацелиться непосредственно на виртуальные машины. Код не обязательно должен быть внутри vb.net я также могу перевести c#.

Дополнительная Отладочная Информация:
Состояние isConnected области управления истинно
OutParams ("sValue") ничего не возвращает

Было бы ооочень приятно, если бы кто-нибудь мог мне помочь в этом деле x.x !

Что я уже пробовал:

Dim strStringValue As String = ""
            Dim objManagementScope As ManagementScope
            Dim objManagementClass As ManagementClass
            Dim objManagementBaseObject As ManagementBaseObject

            Dim intRegistryHive As Integer = 80000002
            Dim strSubKeyName As String = "SOFTWARE\Microsoft\Virtual Machine\Guest\Parameters"
            Dim strValueName As String = "PhysicalHostName"


            strSubKeyName = strSubKeyName.Trim
            strValueName = strValueName.Trim

            If (strSubKeyName.Length > 0) Then
                'Connect to the specified computer registry
                objManagementScope = New ManagementScope

                With objManagementScope
                    With .Path
                        .Server = m_ComputerName
                        .NamespacePath = "root\default"
                    End With

                    With .Options
                        .EnablePrivileges = True
                        .Impersonation = ImpersonationLevel.Impersonate
                        .Username = frmMain.txtUserName.Text
                        .Password = frmMain.txtPassword.Text
                    End With

                    .Connect()
                End With

                'Retrieve the required value from the registry

                If objManagementScope.IsConnected Then
                    objManagementClass = New ManagementClass("StdRegProv")

                    With objManagementClass
                        .Scope = objManagementScope
                        objManagementBaseObject = .GetMethodParameters("GetStringValue")

                        With objManagementBaseObject
                            .SetPropertyValue("hDefKey", CType("&H" & Hex(intRegistryHive), Long))
                            .SetPropertyValue("sSubKeyName", strSubKeyName)
                            .SetPropertyValue("sValueName", strValueName)
                        End With

                        Dim OutParams As ManagementBaseObject = .InvokeMethod("GetStringValue", objManagementBaseObject, Nothing)
                        strStringValue = CType(OutParams("sValue"), String)
                        If strStringValue = Nothing Then strStringValue = ""
                    End With
                End If
            End If

            Return strStringValue
        Catch ex As Exception
            Return ""
        End Try


Проблема, вероятно, где-то в
If objManagementScope.IsConnected Then
               objManagementClass = New ManagementClass("StdRegProv")

               With objManagementClass
                   .Scope = objManagementScope
                   objManagementBaseObject = .GetMethodParameters("GetStringValue")

                   With objManagementBaseObject
                       .SetPropertyValue("hDefKey", CType("&H" & Hex(intRegistryHive), Long))
                       .SetPropertyValue("sSubKeyName", strSubKeyName)
                       .SetPropertyValue("sValueName", strValueName)
                   End With

                   Dim OutParams As ManagementBaseObject = .InvokeMethod("GetStringValue", objManagementBaseObject, Nothing)
                   Dim tst As Object = OutParams("sValue")
                   strStringValue = CType(OutParams("sValue"), String)
                   If strStringValue = Nothing Then strStringValue = ""
               End With
           End If

2 Ответов

Рейтинг:
2

Richard Deeming

Попробуйте использовать классы реестра в Microsoft.Win32 пространство имен:

Using hive = RegistryKey.OpenRemoveBaseKey(RegistryHive.LocalMachine, m_ComputerName, RegistryView.Default)
    Using key = hive.OpenSubKey("SOFTWARE\Microsoft\Virtual Machine\Guest\Parameters", False)
        If key IsNot Nothing Then
            strStringValue = CStr(key.GetValue("PhysicalHostName"))
        End If
    End Using
End Using

Класс RegistryKey / Microsoft Docs[^]


Member 13262965

Привет Ричард,

спасибо, что ответили на мой вопрос:)!

К сожалению, это не сработает для меня, так как OpenRemoteBaseKey, похоже, нуждается в запуске службы RemoteRegistry (которая по умолчанию отключена).

Есть ли другой способ сделать это ?
Или мне нужно использовать RemoteKey и сервис ?

Заранее благодарю вас !

Richard Deeming

Вы должны уметь использовать WMI - в Google есть много примеров. Большинство из них, похоже, используют PowerShell, но есть несколько в C# - например: Чтение значения реестра с помощью WMI в C# [^]

Единственное очевидное отличие от вашего кода - это hDefKey параметр-попробуйте заменить:

.SetPropertyValue("hDefKey", CType("&H" & Hex(intRegistryHive), Long))
с
.SetPropertyValue("hDefKey", intRegistryHive)

Также:
OutParams("sValue")
наверное, так и должно быть
OutParams.Properties("sValue").Value

[no name]

Эй, парень, не мог бы ты помочь мне с моим новым вопросом? Я пытаюсь выяснить, как переместить настольное приложение в случайную папку :)

Member 13262965

Я могу легко заменить строки SetPropertyValue, но когда я заменяю outparams, я получаю HRESULT -2147467259 (= 0x80004005 = неопределенная ошибка), которая, по-видимому, вызвана тем фактом, что OutParams устанавливаются в ничто, когда я пытаюсь восстановить значение .Value .

Интересно, если это что-то сетевое ... что было бы действительно странно, потому что я могу восстановить установленное программное обеспечение(что также делается через реестр через wmi) CPU(через запрос wmi) и т. д. без ошибок.

Member 13262965

Это код, который я использую для получения информации о программном обеспечении... не понимаю, почему это работает абсолютно нормально ..

Private Sub getSoftwareList(ByRef SwLst As SortedList(Of String, SoftwareKomponent), ByVal HKEY As UInteger, ByVal regPath As String, ByVal UserName As String, ByVal SoftwareType As String)

        Dim Sw As SoftwareKomponent

        Dim Path As ManagementPath = New ManagementPath("\\" & m_ComputerName & "\root\default")
        Me.Path = Path

        Dim keyToRead() As String = New String() {"DisplayName", "DisplayVersion", "Publisher"} 'Array mit auszulesenden Werten
        Dim softValue() As String = New String() {"", "", ""} 'Array für gelesene Werte

        Dim DisplayName As String = ""
        Dim DisplayVersion As String = ""
        Dim Publisher As String = ""
        Dim Software As String = ""

        Dim RegMgmPath As ManagementPath = New ManagementPath("StdRegProv") 'Standard Registrierungspfad in "Path" schreiben
        Dim registry As ManagementClass = New ManagementClass(Me, RegMgmPath, Nothing) 'Vollständiger Pfad zur Registry in "registry" schreiben

        Dim methodArgs As Object() = New Object() {HKEY, regPath, Nothing}
        Dim returnValue As UInteger = CUInt(registry.InvokeMethod("EnumKey", methodArgs))

        If methodArgs(2) IsNot Nothing Then
            Dim subKeys As String() = TryCast(methodArgs(2), [String]())

            If Not subKeys Is Nothing Then


                Dim inParams As ManagementBaseObject = registry.GetMethodParameters("GetStringValue")

                For Each subKey As String In subKeys
                    For j As Integer = 0 To keyToRead.GetUpperBound(0)
                        inParams("sSubKeyName") = regPath & subKey
                        inParams("sValueName") = keyToRead(j)

                        Dim outParams1 As ManagementBaseObject = registry.InvokeMethod("GetStringValue", inParams, Nothing)
                        softValue(j) = outParams1("sValue")

                    Next

                    Dim outParams As ManagementBaseObject = registry.InvokeMethod("GetStringValue", inParams, Nothing)

                    Sw = New SoftwareKomponent
                    Sw.UserName = UserName
                    Sw.SoftwareType = SoftwareType
                    Sw.DisplayName = softValue(0)
                    Sw.DisplayVersion = softValue(1)
                    Sw.Publisher = softValue(2)
                    Sw.Software = subKey.ToUpper
                    If Not SwLst.ContainsKey(subKey.ToUpper) Then
                        SwLst.Add(subKey.ToUpper, Sw)
                    End If
                Next

            End If

        End If

    End Sub


End Class

Рейтинг:
2

Member 13262965

Поскольку никто, кажется, не хочет отвечать, я закрываю вопрос. До сих пор я не нашел своей ошибки. Я могу читать все regKeys, кроме того, который я хочу прочитать.


Dave Kreskowiak

Если вы можете получить имена и значения других ключей, кроме этого ключа, это наводит меня на мысль, что безопасность была настроена на этих ключах, делая данные доступными только администраторам и администраторам гипервизора.