2009-09-16 6 views
3

J'ai une liste du nom des ordinateurs partagés de la forme "\\ ordinateur" et j'ai besoin de trouver des dossiers partagés sur ces ordinateurs.Obtenez une liste de répertoires sur un ordinateur partagé .NET

Toutes les méthodes .Net que j'ai pu trouver nécessitent une UNC valide pour être appelée, mais puisque j'ai seulement la liste des ordinateurs, je ne peux pas faire une UNC valide.

Y at-il un moyen de découvrir tous les dossiers partagés sur un ordinateur en utilisant seulement le nom de l'ordinateur (comme "\\ ordinateur")?

Répondre

4

Il n'y a aucun moyen de le faire dans le standard BCL. Vous devrez accéder à la fonction native NetShareEnum à cette fin.

C'est un peu de travail cependant. Heureusement, quelqu'un sur CodeProject l'a déjà fait et a sorti une bibliothèque en l'enveloppant dans une belle API managée.

+2

Mon intuition dit qu'il y a une méthode WMI quelque part, même si cela ne veut pas dire que c'est forcément meilleur que celui de l'API Win. – Noldorin

0

CodeProject a un article qui comprend une enveloppe pour les classes WMI:

WMI wrapper

L'emballage est écrit en VB.NET, mais bien sûr, il peut être construit dans une DLL et appelé à partir de C#.

[Alors noldorin, vous avez raison.]

4

Essayez ce Code,

testé dans Windows XP, Windows Vista.

using System; 
using System.Runtime.InteropServices; 

namespace ConsoleApplication 
{ 

    class Program 
    { 

     public enum RESOURCE_SCOPE_NET 
     { 
     RESOURCE_CONNECTED = 0x00000001, 
     RESOURCE_GLOBALNET = 0x00000002, 
     RESOURCE_REMEMBERED = 0x00000003, 
     RESOURCE_RECENT  = 0x00000004, 
     RESOURCE_CONTEXT = 0x00000005 
     } 

     public enum RESOURCE_TYPE_NET 
     { 
     RESOURCETYPE_ANY  = 0x00000000, 
     RESOURCETYPE_DISK  = 0x00000001, 
     RESOURCETYPE_PRINT = 0x00000002, 
     RESOURCETYPE_RESERVED = 0x00000008, 
     } 

     public enum RESOURCE_USAGE_NET 
     { 
     RESOURCEUSAGE_CONNECTABLE =0x00000001, 
     RESOURCEUSAGE_CONTAINER  =0x00000002, 
     RESOURCEUSAGE_NOLOCALDEVICE =0x00000004, 
     RESOURCEUSAGE_SIBLING  =0x00000008, 
     RESOURCEUSAGE_ATTACHED  =0x00000010, 
     RESOURCEUSAGE_ALL   =(RESOURCEUSAGE_CONNECTABLE | RESOURCEUSAGE_CONTAINER | RESOURCEUSAGE_ATTACHED), 
     } 

     public enum RESOURCE_DISPLAYTYPE_NET 
     { 
      RESOURCEDISPLAYTYPE_GENERIC = 0x00000000, 
      RESOURCEDISPLAYTYPE_DOMAIN = 0x00000001, 
      RESOURCEDISPLAYTYPE_SERVER = 0x00000002, 
      RESOURCEDISPLAYTYPE_SHARE = 0x00000003, 
      RESOURCEDISPLAYTYPE_FILE = 0x00000004, 
      RESOURCEDISPLAYTYPE_GROUP = 0x00000005, 
      RESOURCEDISPLAYTYPE_NETWORK = 0x00000006, 
      RESOURCEDISPLAYTYPE_ROOT = 0x00000007, 
      RESOURCEDISPLAYTYPE_SHAREADMIN = 0x00000008, 
      RESOURCEDISPLAYTYPE_DIRECTORY = 0x00000009, 
      RESOURCEDISPLAYTYPE_TREE   = 0x0000000A, 
      RESOURCEDISPLAYTYPE_NDSCONTAINER = 0x0000000B 
     }  

     [DllImport("mpr.dll", CharSet=CharSet.Auto)] 
     public static extern int WNetEnumResource(
     IntPtr hEnum, 
     ref int lpcCount, 
     IntPtr lpBuffer, 
     ref int lpBufferSize); 

     [DllImport("mpr.dll", CharSet=CharSet.Auto)] 
     public static extern int WNetOpenEnum(RESOURCE_SCOPE_NET dwScope, RESOURCE_TYPE_NET dwType, RESOURCE_USAGE_NET dwUsage, [MarshalAs(UnmanagedType.AsAny)][In] Object lpNetResource, out IntPtr lphEnum); 
     [DllImport("mpr.dll", CharSet=CharSet.Auto)] 
     public static extern int WNetCloseEnum(IntPtr hEnum); 



     public struct NETRESOURCE 
     { 
      public RESOURCE_SCOPE_NET dwScope; 
      public RESOURCE_TYPE_NET dwType; 
      public RESOURCE_DISPLAYTYPE_NET dwDisplayType; 
      public RESOURCE_USAGE_NET dwUsage; 
      [MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPTStr)] 
      public string lpLocalName; 
      [MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPTStr)] 
      public string lpRemoteName; 
      [MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPTStr)] 
      public string lpComment; 
      [MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPTStr)] 
      public string lpProvider; 

     } 


     private static void InitScan(Object Dummy) 

     { 
     int iRet; 
     IntPtr ptrHandle = new IntPtr(); 
     try 

     { 
      iRet = WNetOpenEnum(RESOURCE_SCOPE_NET.RESOURCE_GLOBALNET, RESOURCE_TYPE_NET.RESOURCETYPE_ANY, RESOURCE_USAGE_NET.RESOURCEUSAGE_ALL, Dummy, out ptrHandle); 

     if(iRet != 0) 
     { 
     return; 
     } 

     int entries; 
     int buffer = 16384; 
     IntPtr ptrBuffer = Marshal.AllocHGlobal(buffer); 
     NETRESOURCE nr; 

     for(;;) 
     { 
     entries = -1; 
     buffer = 16384; 
     iRet =WNetEnumResource(ptrHandle, ref entries, ptrBuffer, ref buffer); 

     if((iRet != 0) || (entries < 1)) 
     { 
     break; 
     } 

     Int32 ptr = ptrBuffer.ToInt32(); 
     for(int i = 0; i < entries; i++) 
     { 
     nr = (NETRESOURCE)Marshal.PtrToStructure(new IntPtr(ptr), typeof(NETRESOURCE)); 
     if(RESOURCE_USAGE_NET.RESOURCEUSAGE_CONTAINER == (nr.dwUsage & RESOURCE_USAGE_NET.RESOURCEUSAGE_CONTAINER)) 

     { 
      InitScan(nr); 
     } 

     ptr += Marshal.SizeOf(nr); 
     Console.WriteLine(" {0} : LocalName='{1}' RemoteName='{2}' Description='{3}' Provider='{4}'", nr.dwDisplayType.ToString(), nr.lpLocalName, nr.lpRemoteName,nr.lpComment,nr.lpProvider); 
     } 

     } 

     Marshal.FreeHGlobal(ptrBuffer); 
     iRet =WNetCloseEnum(ptrHandle); 
     } 

     catch(Exception e) 

     { 
      Console.WriteLine("Error ** "+e.Message+" ** Trace "+e.StackTrace); 
     } 

     } 


    static void Main(string[] args) 
    { 
     Console.WriteLine("Scannig Network....Wait a moment , be patient please ;)"); 
     InitScan(null); 
     Console.WriteLine("Scan Network Finished"); 
     Console.Read(); 
    } 
    } 
} 

Salut.

+0

Merci pour le code, cela fonctionne vraiment et vous permet de modifier un peu plus les choses, mais l'API ci-dessus est bien trop belle. Cela pourrait être une meilleure solution si vous êtes familier avec les structures C#. –

Questions connexes