使用其IP地址读取远程计算机上的注册表 - OpenRemoteBaseKey

时间:2016-01-07 00:13:13

标签: .net windows powershell registry

我正在尝试编写一个可以从远程计算机获取某些注册表值的应用程序。用户可以在字符串中提供主机名或IP,并且应该在其屏幕上显示注册表值。当我调试程序时,它发现只要我提供的输入是“localhost”或“127.0.0.1”就会出错,但是当我提供“mxcz”时,它就是我的计算机名。

该应用程序使用Microsoft.Win32.RegistryKey中的OpenRemoteRegistryKey方法。我决定隔离这一行,然后在PowerShell中运行它。您可以看到下图中发生的情况。这两个PowerShell行有效:

[Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine,127.0.0.1)

[Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine,"mxcz")

这些不起作用:

[Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine,"127.0.0.1")

[Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine,localhost)

[Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine,"localhost")

使用我的实际LAN IP地址192.168.0.136而不是127.0.0.1给出了完全相同的行为。它没有引号,但在引号中不起作用。

我认为,我很清楚,为什么第二行有效,为什么第四行没有。但我无法弄清楚为什么第一行有效,为什么第三行和第五行没有。 OpenRemoteRegistryKey方法的Microsoft网页清楚地说第二个参数应该是一个字符串。为什么引号中的“localhost”不起作用呢?为什么没有引号的127.0.0.1有效?我不明白该方法如何解释这个值。为什么引号中的“127.0.0.1”不起作用?

最重要的是,当用户输入是一个字符串时,我怎么能传递方法所需的任何东西,“主机名”或“ipaddress”(不管用户决定使用哪一个,最好使用相同的变量) ?简单地给它添加一个值为“127.0.0.1”的字符串显然不起作用。或者我应该使用不同的方式完全访问远程注册表?

这是在Windows 8.1,x64上。

enter image description here

修改

在C#中,引用版本和未引用版本都不起作用。使用引号,它将给出相同的错误,“找不到网络路径”,没有它们就不会编译,见下文。

enter image description here

3 个答案:

答案 0 :(得分:1)

我认为您的问题是错误是误导性的。其中一个prerequisites of this working是远程注册表服务需要运行。

  

为了远程打开密钥,服务器和客户端计算机都必须运行远程注册表服务,并启用远程管理。

我建议您在自己的计算机和目标计算机上验证服务是否正在运行。我能够通过关闭和打开服务来复制问题。当该方法假设localhost时,它似乎通过本地访问工作。当明确说明时,它似乎试图使用该服务。

此外,你必须引用这些字符串。否则PowerShell将尝试将文本评估为exe / function / cmdlet等。只需键入localhost127.0.0.1,您将从解析器中获得错误。就后者而言:

The property '0.1' cannot be found on this object. Verify that the property exists.

这是我为您的一个工作示例得到的同样的错误......遗憾的是,这似乎没有帮助

PS D:\temp> [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine,127.0.0.1)
The property '0.1' cannot be found on this object. Verify that the property exists.
At line:1 char:1
+ [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey([Microsoft.Win32.RegistryHive]: ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], PropertyNotFoundException
    + FullyQualifiedErrorId : PropertyNotFoundStrict

答案 1 :(得分:0)

问题是PowerShell正在处理127.0.0.1而没有引号奇怪。如果你破解打开powershell并单独输入127.0.0.1,它将返回没有输出且没有错误。如果您尝试执行类似“> 127.0.0.1 | gm”的操作,则会抛出异常。

我注意到,处理两个以上时期的任何事情都会有不同的处理方式。尝试在提示符下键入“127.0”,然后在提示符下键入“127.0.0”。不同的行为。

最后 - 试试这个:

ping 127.0.0.1 #works
ping (127.0.0.1)  #doesn't work -- powershell doing something weird
ping 8.8.8.8 # works 
ping (8.8.8.8) # doesn't work
# the weird part. If you ping after the first octet, ping treats
# anything else as the end... example
# ping 127.1 = "ping 127.0.0.1"  since powershell isn't
# doing it's weirdness on short strings, try:
ping 127.1  # works
ping (127.1) # works

所以 - 我认为,长话短说,PowerShell正在为该IP地址做一些奇怪的事情而不必引用它。我会喜欢一些可能比我潜水深的人的其他信息。

答案 2 :(得分:0)

<强>的PowerShell

我认为这可能是由于PowerShell在早期版本中进行Type Inference的方式,因为我在Windows 10上使用PowerShell 5时没有看到相同的结果。

PowerShell有自己独特的方式来找出使用某种.Net方法所需的类型:

例如:

[Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine,"127.0.0.1")

[Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey("LocalMachine","127.0.0.1")

是相同的,唯一的区别是PowerShell会在运行时将"LocalMachine"翻译为[Microsoft.Win32.RegistryHive]::LocalMachine,因为OpenRemoteBaseKey要求第一个参数属于Microsoft.Win32.RegistryHive类型。

以下是您可以尝试的一些事项:

(1)让PowerShell首先评估变量,然后将变量传递给OpenRemoteBaseKey,PowerShell将调整变量而不是字符串:

$computer = "127.0.0.1"
[Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey("LocalMachine",$computer)

(2)使用文字引号告诉PowerShell你想要直接传递127.0.0.1:

[Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey("LocalMachine",'127.0.0.1')

<强> C#

它在C#中不起作用的原因是因为与Powershell 127.0.0.1不同,没有引号对任何东西都不是有效的语法(如错误消息中所述)。

如果您将IP地址放在引号中,您将告诉C#您要连接的计算机LocalMachine:

RegistryKey fd = RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, @"127.0.0.1");

希望这有帮助,如果您取得任何进展,请告诉我们。)

相关问题