2009-10-14 8 views
8

Ho bisogno di essere in grado di leggere i valori in una specifica chiave del Registro da un elenco di computer remoti. posso fare questo a livello locale con il seguente codiceCome leggere le chiavi di registro remote?

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()); 
     } 

ma non so come ottenere le stesse informazioni per un computer remoto. Sto anche usando l'approccio giusto o dovrei guardare WMI o qualcos'altro?

+1

Hai considerato WMI? –

risposta

12

È possibile raggiungere questo obiettivo attraverso WMI, anche se credo che si può anche ottenere tramite lo stesso meccanismo (vale a dire Microsoft.Win32 classi namespace), che si sta attualmente utilizzando.

avete bisogno di guardare in:

OpenRemoteBaseKey Method

Il link di cui sopra dà esempi. E 'dovrebbe essere semplice come qualcosa di simile a:

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

nota, però, che ti ci saranno implicazioni per la sicurezza in apertura di chiavi di registro remoto, quindi potrebbe essere necessario per garantire che si dispone delle autorizzazioni di protezione importanti per fare questo . Per questo, ti consigliamo di guardare il:

SecurityPermission

e

RegistryPermission

classi del namespace System.Security.Permissions.

+1

accettato come risposta e maggiori informazioni su come l'ho usato per risolvere il mio problema in una risposta di seguito. – etoisarobot

1

L'API Win32 permette di specificare un nome di computer attraverso RegConnectRegistry. Non sono sicuro che i wrapper .NET espongano questo. Puoi anche usare WMI come hai detto.

1

Guardi su OpenRemoteBaseKey().

9

Ho scoperto che potrei come CraigTP ha mostrato utilizzare il metodo OpenRemoteBaseKey() tuttavia mi ha richiesto di modificare le autorizzazioni nel Registro di sistema sui computer di destinazione.

Ecco il codice che ho scritto che lavoravo una volta ho cambiato i permessi.

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()); 
} 

Ho anche trovato che potrei ottenere le stesse informazioni usando WMI senza dover modificare i permessi. Ecco il codice con 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); 
} 

P.S. Sto chiamando il metodo GetStringValue() nel ciclo come so che tutti i valori sono stringhe. Se sono disponibili più tipi di dati, è necessario leggere il tipo di dati dal parametro di output Tipi del metodo EnumValues.

+0

Quali autorizzazioni sono state modificate in modo che "OpenRemoteBaseKey" funzionasse? Grazie! – boboes

1

Un commentatore sul mio blog mi ha chiesto di pubblicare la mia soluzione sullo stack overflow, quindi eccolo qui.

How to authenticate and access the registry remotely using C#

E 'fondamentalmente la stessa risposta di CraigTP, ma include una bella classe per l'autenticazione al dispositivo remoto.

E il codice è in produzione e testato.

1

Questa è la soluzione sono andato con alla fine:

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); 
      } 
     } 
    } 
} 

funziona come un fascino:]

1

Facile esempio nei programmi C installati # tramite registro di Windows (a distanza: 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(); 
     } 


    } 
}