2010-08-25 11 views
16

Estoy tratando de obtener una lista de todas las carpetas compartidas disponibles en un servidor de intranet local.Obtenga una lista de todas las carpetas compartidas de UNC en un servidor de red local

El System.IO.Directory.GetDirectories() funciona bien para un camino como \\myServer\myShare, sin embargo yo estoy haciendo una excepción para un camino como \\myServer:

Excepción no controlada: System.ArgumentException: La ruta UNC debe ser de la forma \ servidor \compartir.

¿Hay alguna manera de obtener una lista de todas las carpetas compartidas para un servidor? En definitiva, estoy buscando un método que pueda manejar ambos escenarios en función de una ruta determinada: devolver una lista de todos los recursos compartidos para un servidor determinado y devolver una lista de todos los subdirectorios para una determinada carpeta compartida de red.

+2

posible duplicado de [Enumerar recursos compartidos de red con C#] (http://stackoverflow.com/questions/2091126/enumerating-network-shares-with -c) – kbrimington

+0

@kbrimington esta Q pregunta por remota, que Q solo pregunta por local. – Richard

+1

@Richard: la respuesta aceptada también abarca a distancia. – kbrimington

Respuesta

3
+2

Gracias, esto funcionó para mí. Terminé escribiendo un método que amplía System.IO.Directory.GetDirectories().Utiliza expresiones regulares para averiguar qué tipo de ruta se da (// servidor/compartir o simplemente // servidor) y luego llama a Directory.GetDirectories() o a la biblioteca de CodeProject, respectivamente. –

5

Aquí es una técnica que utiliza System.Management (añadir una referencia a este conjunto): Se requieren

using (ManagementClass shares = new ManagementClass(@"\\NameOfTheRemoteComputer\root\cimv2", "Win32_Share", new ObjectGetOptions())) { 
    foreach (ManagementObject share in shares.GetInstances()) { 
     Console.WriteLine(share["Name"]); 
    } 
} 

permisos apropiados.

+1

Gracias, Bradley. Su técnica funcionó bien para enumerar acciones en mi máquina local, sin embargo, me dio la excepción 'System.Management.ManagementException: Access denied' cuando intenté acceder al servidor en una red local. Al mismo tiempo, la otra solución (utiliza P/Invoke) funcionó bien para el mismo servidor. –

+0

Sí, lo he comprobado y tienes razón. Creo que hay más en WMI de lo que parece, incluida la necesidad de trabajar con las clases ConnectionOptions y ManagementScope de cierta manera para acceder a computadoras remotas. Estoy seguro de que es posible, pero en este momento no tengo la experiencia para describir cómo hacerlo. –

+0

Funcionó como un amuleto para mí (golpear una máquina de eliminación). Sin embargo, corría como yo y mi usuario tiene derechos de administrador en la máquina de destino. –

2
private DataTable GetSharedFolderAccessRule() 
    { 
     DataTable DT = new DataTable(); 

     try 
     { 
      DT.Columns.Add("ShareName"); 
      DT.Columns.Add("Caption"); 
      DT.Columns.Add("Path"); 
      DT.Columns.Add("Domain"); 
      DT.Columns.Add("User"); 
      DT.Columns.Add("AccessMask"); 
      DT.Columns.Add("AceType"); 

      ManagementScope Scope = new ManagementScope(@"\\.\root\cimv2"); 
      Scope.Connect(); 
      ObjectQuery Query = new ObjectQuery("SELECT * FROM Win32_LogicalShareSecuritySetting"); 
      ManagementObjectSearcher Searcher = new ManagementObjectSearcher(Scope, Query); 
      ManagementObjectCollection QueryCollection = Searcher.Get(); 

      foreach (ManagementObject SharedFolder in QueryCollection) 
      { 
       { 
        String ShareName = (String) SharedFolder["Name"]; 
        String Caption = (String)SharedFolder["Caption"]; 
        String LocalPath = String.Empty; 
        ManagementObjectSearcher Win32Share = new ManagementObjectSearcher("SELECT Path FROM Win32_share WHERE Name = '" + ShareName + "'"); 
        foreach (ManagementObject ShareData in Win32Share.Get()) 
        { 
         LocalPath = (String) ShareData["Path"]; 
        } 

        ManagementBaseObject Method = SharedFolder.InvokeMethod("GetSecurityDescriptor", null, new InvokeMethodOptions()); 
        ManagementBaseObject Descriptor = (ManagementBaseObject)Method["Descriptor"]; 
        ManagementBaseObject[] DACL = (ManagementBaseObject[])Descriptor["DACL"]; 
        foreach (ManagementBaseObject ACE in DACL) 
        { 
         ManagementBaseObject Trustee = (ManagementBaseObject)ACE["Trustee"]; 

         // Full Access = 2032127, Modify = 1245631, Read Write = 118009, Read Only = 1179817 
         DataRow Row = DT.NewRow(); 
         Row["ShareName"] = ShareName; 
         Row["Caption"] = Caption; 
         Row["Path"]  = LocalPath; 
         Row["Domain"]  = (String) Trustee["Domain"]; 
         Row["User"]  = (String) Trustee["Name"]; 
         Row["AccessMask"] = (UInt32) ACE["AccessMask"]; 
         Row["AceType"] = (UInt32) ACE["AceType"]; 
         DT.Rows.Add(Row); 
         DT.AcceptChanges(); 
        } 
       } 
      } 
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show(ex.StackTrace, ex.Message); 
     } 

     return DT; 
    } 
Cuestiones relacionadas