2009-09-16 5 views
3

У меня есть список имен общих компьютеров формы «\\ computer» и вам нужно найти общие папки на этих машинах.Получить список каталогов на общем компьютере. NET

Все методы. Net, которые мне удалось найти, требуют действительного вызова UNC, но поскольку у меня есть только список компьютеров, я не могу создать действительный UNC.

Есть ли способ обнаружить все общие папки на компьютере, используя только имя компьютера (например, «\\ computer»)?

ответ

4

В стандартном BCL нет возможности сделать это. Для этой цели вам понадобится доступ к собственной функции NetShareEnum.

Это немного работа. К счастью, кто-то из CodeProject уже сделал это и выпустил библиотеку, которая обернула ее в хороший управляемый API.

+2

Моя интуиция говорит, что где-то есть метод WMI, хотя это не означает, что это обязательно лучше, чем Win API. – Noldorin

0

CodeProject есть статья, которая включает в себя оболочку для классов WMI:

WMI wrapper

Обертка написана в VB.NET, но, конечно, это может быть построено в DLL и вызывается из C#.

[Так нолдорин, ты прав.]

4

Попробуйте этот код,

Испытано в 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(); 
    } 
    } 
} 

До свидания.

+0

Спасибо за код, он определенно работает и позволяет вам немного настраивать вещи, но API выше просто слишком хорош. Это может быть лучшим решением, если вы знакомы с структурами C#. –

Смежные вопросы