如何读取远程注册表项?

我需要能够从远程计算机列表中读取特定注册表项中的值。 我可以使用以下代码在本地执行此操作

using Microsoft.Win32; RegistryKey rkey = Registry.LocalMachine; RegistryKey rkeySoftware=rkey.OpenSubKey("Software"); RegistryKey rkeyVendor = rkeySoftware.OpenSubKey("VendorName"); RegistryKey rkeyVersions = rkeyVendor.OpenSubKey("Versions"); String[] ValueNames = rkeyVersions.GetValueNames(); foreach (string name in ValueNames) { MessageBox.Show(name + ": " + rkeyVersions.GetValue(name).ToString()); } 

但我不知道如何获得远程计算机的相同信息。 我甚至使用正确的方法,还是应该关注WMI或其他什么?

你可以通过WMI实现这一点,虽然我认为你也可以通过你当前使用的相同机制(即Microsoft.Win32命名空间类)来实现它。

你需要调查:

OpenRemoteBaseKey方法

上面的链接给出了示例。 它应该像下面这样简单:

 // Open HKEY_CURRENT_USER\Environment // on a remote computer. environmentKey = RegistryKey.OpenRemoteBaseKey( RegistryHive.CurrentUser, remoteName).OpenSubKey( "Environment"); 

但请注意,打开远程注册表项会产生安全隐患,因此您可能需要确保拥有相关的安全权限才能执行此操作。 为此,您需要查看:

性SecurityPermission

RegistryPermission的

System.Security.Permissions命名空间中的类。

我发现我可以像CraigTP显示使用OpenRemoteBaseKey()方法但是它要求我更改dest计算机上的注册表中的权限。

这是我编写的代码,一旦我更改了权限。

 RegistryKey rkey = RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, "RemoteComputer"); RegistryKey rkeySoftware = rkey.OpenSubKey("Software"); RegistryKey rkeyVendor = rkeySoftware.OpenSubKey("VendorName"); RegistryKey rkeyVersions = rkeyVendor.OpenSubKey("Versions"); String[] ValueNames = rkeyVersions.GetValueNames(); foreach (string name in ValueNames) { MessageBox.Show(name + ": " + rkeyVersions.GetValue(name).ToString()); } 

我还发现,我可以使用WMI获得相同的信息,而无需修改权限。 这是WMI的代码。

 ManagementScope ms = new ManagementScope(); ms.Path.Server = "flebbe"; ms.Path.NamespacePath = "root\\default"; ms.Options.EnablePrivileges = true; ms.Connect(); ManagementClass mc = new ManagementClass("stdRegProv"); mc.Scope = ms; ManagementBaseObject mbo; mbo = mc.GetMethodParameters("EnumValues"); mbo.SetPropertyValue("sSubKeyName", "SOFTWARE\\VendorName\\Versions"); string[] subkeys = (string[])mc.InvokeMethod("EnumValues", mbo, null).Properties["sNames"].Value; ManagementBaseObject mboS; string keyValue; foreach (string strKey in subkeys) { mboS = mc.GetMethodParameters("GetStringValue"); mboS.SetPropertyValue("sSubKeyName", "SOFTWARE\\VendorName\\Versions"); mboS.SetPropertyValue("sValueName", strKey); keyValue = mc.InvokeMethod("GetStringValue", mboS, null).Properties["sValue"].Value.ToString(); MessageBox.Show(strKey + " : " + keyValue); } 

PS我在循环中调用GetStringValue()方法,因为我知道所有的值都是字符串。 如果有多种数据类型,则需要从EnumValues方法的Types输出参数中读取数据类型。

win32 API允许您通过RegConnectRegistry指定计算机名称。 我不确定.NET包装器会暴露这个。 您也可以按照提到的那样使用WMI。

查找OpenRemoteBaseKey()。

我博客上的一位评论者要求我在堆栈溢出时发布我的解决方案,所以就在这里。

如何使用C#远程validation和访问注册表

它与CraigTP的答案基本相同,但它包含一个用于对远程设备进行身份validation的优秀类。

代码正在生产和测试中。

这是我最终采用的解决方案:

 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; // add a reference to Cassia (MIT license) // https://code.google.com/p/cassia/ using Microsoft.Win32; namespace RemoteRegistryRead2 { class Program { static void Main(string[] args) { String domain = "theDomain"; String user = "theUserName"; String password = "thePassword"; String host = "machine-x11"; using (Cassia.UserImpersonationContext userContext = new Cassia.UserImpersonationContext(domain + "\\" + user, password)) { string userName = System.Security.Principal.WindowsIdentity.GetCurrent().Name; System.Console.WriteLine("userName: " + userName); RegistryKey baseKey = RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, host); RegistryKey key = baseKey.OpenSubKey(@"SYSTEM\CurrentControlSet\Control\ComputerName\ComputerName"); String computerName = key.GetValue("ComputerName").ToString(); Console.WriteLine(computerName); } } } } 

奇迹般有效 :]

通过Windows注册表安装程序的简单示例(远程:OpenRemoteBaseKey)

 using Microsoft.Win32; using System; using System.Collections.Generic; using System.Text; using System.IO; namespace SoftwareInventory { class Program { static void Main(string[] args) { //!!!!! Must be launched with a domain administrator user!!!!! Console.ForegroundColor = ConsoleColor.Green; StringBuilder sbOutFile = new StringBuilder(); Console.WriteLine("DisplayName;IdentifyingNumber"); sbOutFile.AppendLine("Machine;DisplayName;Version"); //Retrieve machine name from the file :File_In/collectionMachines.txt //string[] lines = new string[] { "NameMachine" }; string[] lines = File.ReadAllLines(@"File_In/collectionMachines.txt"); foreach (var machine in lines) { //Retrieve the list of installed programs for each extrapolated machine name var registry_key = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"; using (Microsoft.Win32.RegistryKey key = RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, machine).OpenSubKey(registry_key)) { foreach (string subkey_name in key.GetSubKeyNames()) { using (RegistryKey subkey = key.OpenSubKey(subkey_name)) { //Console.WriteLine(subkey.GetValue("DisplayName")); //Console.WriteLine(subkey.GetValue("IdentifyingNumber")); if (subkey.GetValue("DisplayName") != null) { Console.WriteLine(string.Format("{0};{1};{2}", machine, subkey.GetValue("DisplayName"), subkey.GetValue("Version"))); sbOutFile.AppendLine(string.Format("{0};{1};{2}", machine, subkey.GetValue("DisplayName"), subkey.GetValue("Version"))); } } } } } //CSV file creation var fileOutName = string.Format(@"File_Out\{0}_{1}.csv", "Software_Inventory", DateTime.Now.ToString("yyyy_MM_dd_HH_mmssfff")); using (var file = new System.IO.StreamWriter(fileOutName)) { file.WriteLine(sbOutFile.ToString()); } //Press enter to continue Console.WriteLine("Press enter to continue !"); Console.ReadLine(); } } }