2009-10-14 26 views
8

Necesito poder leer los valores en una clave de registro específica de una lista de equipos remotos. puedo hacer esto a nivel local con el siguiente código¿Cómo leer las claves de registro remoto?

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

pero no saber cómo obtener la misma información para un equipo remoto. ¿Estoy usando el enfoque correcto o debería estar mirando WMI u otra cosa?

+1

¿Has considerado WMI? –

Respuesta

12

Puede lograr esto a través de WMI, aunque creo que también puede lograrlo a través del mismo mecanismo (es decir, las clases de espacio de nombres Microsoft.Win32) que está utilizando actualmente.

que hay que buscar en el:

OpenRemoteBaseKey Method

El enlace anterior proporciona ejemplos. Es debería ser tan simple como algo parecido a:

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

nota, sin embargo, eso no habrá consecuencias para la seguridad en la apertura de las claves de registro remotos, por lo que puede que tenga que asegurarse de que tiene los permisos de seguridad pertinentes para hacer esto . Para ello, tendrá que buscar en el:

SecurityPermission

y

RegistryPermission

clases en el espacio de nombres System.Security.Permissions.

+1

acepté esto como la respuesta y puse más información sobre cómo lo usé para resolver mi problema en una respuesta a continuación. – etoisarobot

1

La API win32 le permite especificar un nombre de computadora a través de RegConnectRegistry. No estoy seguro de que los .NET wrappers exponen esto. También puedes usar WMI como mencionaste.

1

Buscar OpenRemoteBaseKey().

9

Me pareció que CraigTP mostró como usar el método OpenRemoteBaseKey() sin embargo, me requirió cambiar los permisos en el registro en las computadoras dest.

Aquí está el código que escribí que funcionó una vez que cambié los permisos.

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

También encontré que podía obtener la misma información usando WMI sin tener que modificar los permisos. Aquí está el código 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. Estoy llamando al método GetStringValue() en el bucle porque sé que todos los valores son cadenas. Si hay varios tipos de datos, necesitará leer el tipo de datos del parámetro de salida Tipos del método EnumValues.

+0

¿Qué permisos cambiaste para que funcionase "OpenRemoteBaseKey"? ¡Gracias! – boboes

1

Un comentarista en mi blog me pidió que publicara mi solución en el desbordamiento de pila, así que aquí está.

How to authenticate and access the registry remotely using C#

es básicamente la misma que la respuesta de CraigTP, pero incluye una clase agradable para la autenticación en el dispositivo remoto.

Y el código está en producción y probado.

1

Ésta es la solución Fui con en el fin:

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

funciona como un encanto:]

1

Fácil ejemplo, en programas de C# instalado a través de registro de las ventanas (remoto: 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(); 
     } 


    } 
} 
Cuestiones relacionadas