2009-12-13 20 views
8

Uygulamamdaki tüm yerel sürücüleri listelemeye çalışıyorum ve DriveInfo.GetDrives yerel sürücü harflerini geri veriyor ve eşlenmiş sürücülere de ihtiyacım var.Eşlenen ağ sürücüleri C# olarak listelenemez

Şu an için: C :, D: ve G: (HDD), E: ve F: (CD) ve S: ve Z: (eşlenen ağ sürücüleri). (Evet, hepsi Windows Gezgini'nde ve Total Commander'da da görülebilir.) Xzx3 Ancak yalnızca C, D, E, F, G program aracılığıyla alınır.

Ayrıca Environment.GetLogicalDrives(), GetLogicalDriveStrings (pInvoke), FindFirstVolume ve FindNextVolumen (pInvoke) denedim. Eşlenen sürücü listesini kayıt defterinde bulmaya çalıştım. Hiçbir şey işe yaramaz, sadece HDD ve CD harfleri geri alınır.

Herhangi bir istisna yok, doğrudan WinAPI çağrılarında hata yok ve şimdi takılıyorum. Bir çeşit güvenlik ayarı var mı? Baktığım her yer, insanlar DriveInfo.GetDrives'ün eşlenmiş sürücüleri geri vermesi gerektiğini söylüyor. Gerçekten doğru mu?

Vista Home Pro kullanıyorum. Uygulama yerel makineden çalışıyor ve Visual   Studio   2008 ile de burada oluşturuldu. Xzx47

Kullandığım şeyi gönderiyorum, ancak çok basit, yanlış bir şey yapmam mümkün değil:

foreach (System.IO.DriveInfo di in System.IO.DriveInfo.GetDrives()) 
    Console.WriteLine(di.Name); 

Sonuç: D: \ E: \ F: \ G: \ Devam etmek için herhangi bir tuşa basın. . .

Nasıl çalıştırabilirim?

+0

Bunu kullanıcı modunda mı yoksa bir serviste mi çalıştırıyorsunuz? –

+0

Kullanıcı modunda.Mükemmel normal konsol uygulaması veya WinForm uygulaması. – Zolka

cevap

5

Environment.GetLogicalDrives() ve DriveInfo.GetDrives() hem tüm ağ sürücüleri döndü.

Başvurunuz farklı bir kullanıcı (Örneğin bir asp.net web sitesi) olarak çalışıyor mu? Öyleyse, sürücüler aslında bu kullanıcı için eşlenmiş mi? Sürücülerin sizin için eşlendiğini, ancak uygulamanızın çalıştığı kullanıcı için gerçekten eşlenmediklerini görebilirsiniz.

+0

Hayır, bir WinForm uygulaması ve kullanıcıları değiştirmedim. Bu, UAC (açık tuttuğum) uygulamasının normal kullanıcıyla başlamasına neden olurken, eşlenen sürücüler gerçek (yönetici) kullanıcımla bağlantılı olabilir mi? Bundan şüphe ederim ... ama belki. – Zolka

+1

Şüpheliyim, genellikle dosya paylaşımlarını görmek için yönetici erişimi vermeniz gerekmez. Uygulamayı yalnızca görmek için yönetici olarak çalıştırmayı deneyebilirsiniz. Bakabileceğin bir şey, System.Security.Principal.WindowsIdentity.GetCurrent() adıdır. Hangi kullanıcının çalışmakta olduğunu anlatacak isim, sadece emin olmak için. – fyjham

+0

UAC olmadan denedim, stilll çalışmıyor. Mevcut kullanıcıyı uygulamadan kontrol ettim ve kullandım aynı. Bu arada, eşlenen sürücüler ayrılmıştır. Bunun bir farklılık anlamına geleceğini sanmıyorum, ama belki yardımcı olur. – Zolka

8

Tamam, Vista bağlantısız sürücüleri nasıl öğrendim. Kolay değil, bu ama yapılabilir geçerli:

  • WNetOpenEnum
  • WNetEnumResource
  • WNetCloseEnum

ve bu:

Öncelikle, aşağıdaki WinAPI fonksiyonlarının PInvoke tanımını gerekir bir yapıya ve bazı enumlara da ihtiyaç var.

O zaman bunları birden çok kez aramanız gerekir ve sonunda listeyi alırsınız. Sen WNetResource() aramak lazım

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

    [DllImport("MPR.dll", CharSet = CharSet.Auto)] 
    static extern int WNetOpenEnum(RESOURCE_SCOPE dwScope, RESOURCE_TYPE dwType, RESOURCE_USAGE dwUsage, 
     [MarshalAs(UnmanagedType.AsAny)][In] object lpNetResource, out IntPtr lphEnum); 

    [DllImport("MPR.dll", CharSet = CharSet.Auto)] 
    static extern int WNetCloseEnum(IntPtr hEnum); 

    public enum RESOURCE_SCOPE : uint 
    { 
     RESOURCE_CONNECTED = 0x00000001, 
     RESOURCE_GLOBALNET = 0x00000002, 
     RESOURCE_REMEMBERED = 0x00000003, 
     RESOURCE_RECENT = 0x00000004, 
     RESOURCE_CONTEXT = 0x00000005 
    } 
    public enum RESOURCE_TYPE : uint 
    { 
     RESOURCETYPE_ANY = 0x00000000, 
     RESOURCETYPE_DISK = 0x00000001, 
     RESOURCETYPE_PRINT = 0x00000002, 
     RESOURCETYPE_RESERVED = 0x00000008, 
    } 
    public enum RESOURCE_USAGE : uint 
    { 
     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 : uint 
    { 
     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 
    } 

    [StructLayout(LayoutKind.Sequential)] 
    public struct NetResource 
    { 
     public RESOURCE_SCOPE dwScope; 
     public RESOURCE_TYPE dwType; 
     public RESOURCE_DISPLAYTYPE dwDisplayType; 
     public RESOURCE_USAGE 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; 
    } 

    static System.Collections.Generic.Dictionary<string, NetResource> WNetResource(object resource) 
    { 
     System.Collections.Generic.Dictionary<string, NetResource> result = new System.Collections.Generic.Dictionary<string, NetResource>(); 

     int iRet; 
     IntPtr ptrHandle = new IntPtr(); 
     try 
     { 
      iRet = WNetOpenEnum(
       RESOURCE_SCOPE.RESOURCE_REMEMBERED, RESOURCE_TYPE.RESOURCETYPE_DISK, RESOURCE_USAGE.RESOURCEUSAGE_ALL, 
       resource, out ptrHandle); 
      if (iRet != 0) 
       return null; 

      int entries = -1; 
      int buffer = 16384; 
      IntPtr ptrBuffer = Marshal.AllocHGlobal(buffer); 
      NetResource nr; 

      iRet = WNetEnumResource(ptrHandle, ref entries, ptrBuffer, ref buffer); 
      while ((iRet == 0) || (entries > 0)) 
      { 
       Int32 ptr = ptrBuffer.ToInt32(); 
       for (int i = 0; i < entries; i++) 
       { 
        nr = (NetResource)Marshal.PtrToStructure(new IntPtr(ptr), typeof(NetResource)); 
        if (RESOURCE_USAGE.RESOURCEUSAGE_CONTAINER == (nr.dwUsage 
         & RESOURCE_USAGE.RESOURCEUSAGE_CONTAINER)) 
        { 
         //call recursively to get all entries in a container 
         WNetResource(nr); 
        } 
        ptr += Marshal.SizeOf(nr); 
        result.Add(nr.lpLocalName, nr); 
       } 

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

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

     return result; 
    } 
    public static System.Collections.Generic.Dictionary<string, NetResource> WNetResource() 
    { 
     return WNetResource(null); 
    } 

ve sürücülerin listesini geri alacak: İşte uzun, dikkat, kodudur. (ve kek :-))

İlgili konular