Comment lire les clés de registre à distance?

Je dois pouvoir lire les valeurs d’une clé de registre spécifique à partir d’une liste d’ordinateurs distants. Je peux le faire localement avec le code suivant

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

mais je ne sais pas comment obtenir les mêmes informations pour un ordinateur distant. Est-ce que j’utilise même la bonne approche ou devrais-je regarder WMI ou autre chose?

Vous pouvez y parvenir via WMI, même si je pense que vous pouvez également y parvenir via le même mécanisme (par exemple, les classes d’espace de noms Microsoft.Win32) que vous utilisez actuellement.

Vous devez regarder dans le:

OpenRemoteBaseKey, méthode

Le lien ci-dessus donne des exemples. Cela devrait être aussi simple que quelque chose comme:

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

Notez cependant que l’ouverture de clés de registre distantes aura des implications en termes de sécurité. Vous devrez peut-être vous assurer que vous disposez des permissions de sécurité appropriées à cette fin. Pour cela, vous aurez envie d’examiner:

SécuritéPermission

et

RegistryPermission

classes dans l’espace de noms System.Security.Permissions .

J’ai constaté que, comme CraigTP avait montré, je pouvais utiliser la méthode OpenRemoteBaseKey (), mais que cela nécessitait que je modifie les permissions du registre sur les ordinateurs destin.

Voici le code que j’ai écrit et qui a fonctionné une fois les permissions modifiées.

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

J’ai également constaté que je pouvais obtenir les mêmes informations à l’aide de WMI sans avoir à modifier les permissions. Voici le code avec 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"); ssortingng[] subkeys = (ssortingng[])mc.InvokeMethod("EnumValues", mbo, null).Properties["sNames"].Value; ManagementBaseObject mboS; ssortingng keyValue; foreach (ssortingng strKey in subkeys) { mboS = mc.GetMethodParameters("GetSsortingngValue"); mboS.SetPropertyValue("sSubKeyName", "SOFTWARE\\VendorName\\Versions"); mboS.SetPropertyValue("sValueName", strKey); keyValue = mc.InvokeMethod("GetSsortingngValue", mboS, null).Properties["sValue"].Value.ToSsortingng(); MessageBox.Show(strKey + " : " + keyValue); } 

PS J’appelle la méthode GetSsortingngValue () dans la boucle car je sais que toutes les valeurs sont des chaînes. S’il existe plusieurs types de données, vous devez lire le type de données à partir du paramètre de sortie Types de la méthode EnumValues.

L’API win32 vous permet de spécifier un nom d’ordinateur via RegConnectRegistry . Je ne suis pas sûr que les wrappers .NET exposent cela. Vous pouvez également utiliser WMI comme vous l’avez mentionné.

Recherchez OpenRemoteBaseKey ().

Un commentateur de mon blog m’a demandé de publier ma solution sur le débordement de stack, alors le voici.

Comment s’authentifier et accéder au registre à distance à l’aide de C #

C’est fondamentalement la même chose que la réponse de CraigTP, mais elle inclut une classe intéressante pour l’authentification sur le périphérique distant.

Et le code est en production et testé.

Voici la solution que j’ai choisie:

 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(ssortingng[] args) { Ssortingng domain = "theDomain"; Ssortingng user = "theUserName"; Ssortingng password = "thePassword"; Ssortingng host = "machine-x11"; using (Cassia.UserImpersonationContext userContext = new Cassia.UserImpersonationContext(domain + "\\" + user, password)) { ssortingng 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"); Ssortingng computerName = key.GetValue("ComputerName").ToSsortingng(); Console.WriteLine(computerName); } } } } 

Fonctionne comme un charme:]

Exemple simple dans les programmes installés c # via le registre Windows (à distance: OpenRemoteBaseKey)

 using Microsoft.Win32; using System; using System.Collections.Generic; using System.Text; using System.IO; namespace SoftwareInventory { class Program { static void Main(ssortingng[] args) { //!!!!! Must be launched with a domain administrator user!!!!! Console.ForegroundColor = ConsoleColor.Green; SsortingngBuilder sbOutFile = new SsortingngBuilder(); Console.WriteLine("DisplayName;IdentifyingNumber"); sbOutFile.AppendLine("Machine;DisplayName;Version"); //Resortingeve machine name from the file :File_In/collectionMachines.txt //ssortingng[] lines = new ssortingng[] { "NameMachine" }; ssortingng[] lines = File.ReadAllLines(@"File_In/collectionMachines.txt"); foreach (var machine in lines) { //Resortingeve 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 (ssortingng 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(ssortingng.Format("{0};{1};{2}", machine, subkey.GetValue("DisplayName"), subkey.GetValue("Version"))); sbOutFile.AppendLine(ssortingng.Format("{0};{1};{2}", machine, subkey.GetValue("DisplayName"), subkey.GetValue("Version"))); } } } } } //CSV file creation var fileOutName = ssortingng.Format(@"File_Out\{0}_{1}.csv", "Software_Inventory", DateTime.Now.ToSsortingng("yyyy_MM_dd_HH_mmssfff")); using (var file = new System.IO.StreamWriter(fileOutName)) { file.WriteLine(sbOutFile.ToSsortingng()); } //Press enter to continue Console.WriteLine("Press enter to continue !"); Console.ReadLine(); } } }