2009-12-13 4 views
8

으로 나열 할 수 없습니다. 응용 프로그램에서 모든 로컬 드라이브를 나열하려고 시도하고 DriveInfo.GetDrives 로컬 드라이브 문자를 돌려 주었고 매핑 된 드라이브도 필요합니다.매핑 된 네트워크 드라이브를 C#

현재 C :, D : 및 G : (HDD), E : 및 F : (CD) 및 S : 및 Z : (매핑 된 네트워크 드라이브) (예, 모두 Windows 탐색기에서 볼 수 있으며 Total Commander도 있습니다.) 그러나 프로그래밍 방식으로 C, D, E, F, G 만 검색됩니다.

Environment.GetLogicalDrives(), GetLogicalDriveStrings (pInvoke), FindFirstVolumeFindNextVolumen (pInvoke)도 시도했습니다. 매핑 된 드라이브 목록을 레지스트리에서 찾으려고했습니다. 아무것도 작동하지 않고 HDD 및 CD 편지 만 수집됩니다.

예외가 발생하지 않으며 직접 WinAPI 호출에 오류가 표시되지 않고 멈추었습니다. 어떤 종류의 보안 설정입니까? 내가 보는 곳마다 사람들은 DriveInfo.GetDrives이 매핑 된 드라이브를 돌려줘야한다고 말한다. 정말 사실입니까?

저는 Vista Home Pro를 사용하고 있습니다.   2008 년

내가 무엇을 사용 게시,하지만 그렇게 간단하다, 그것이 내가 뭔가 잘못 할 경우 수 없습니다 응용 프로그램은 로컬 컴퓨터에서 실행되고, 그것은 비주얼   Studio에 너무 여기에 내장되어 있습니다 :

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

결과 : C : D \ : \ E : \ F : \ G : 계속하려면 아무 키나 을 눌러 \. . .

어떻게 작동합니까?

+0

사용자 모드 또는 서비스에서 이것을 실행하고 있습니까? –

+0

사용자 모드입니다.완벽하게 정상적인 콘솔 응용 프로그램 또는 WinForm 응용 프로그램. – Zolka

답변

5

Environment.GetLogicalDrives()DriveInfo.GetDrives() 모두 내 네트워크 드라이브를 모두 반환했습니다.

응용 프로그램이 다른 사용자 (예 : asp.net 웹 사이트)로 실행되고 있습니까? 그렇다면 드라이브가 해당 사용자에 대해 실제로 매핑되어 있습니까? 드라이브가 매핑되었지만 응용 프로그램이 실행중인 사용자에 대해 실제로 매핑되지 않은 것을 알 수 있습니다.

+0

아니요, WinForm 응용 프로그램이며 사용자를 변경하지 않았습니다. 매핑 된 드라이브가 실제 (관리자) 사용자와 연결되어 있지만 UAC (계속 켜져 있음)가 일반 사용자와 함께 내 앱을 시작할 수 있습니까? 나는 그것을 의심하지만 ... 아마도. – Zolka

+1

의심 스럽지만 일반적으로 관리자에게 파일 공유를 볼 수있는 액세스 권한을 부여하지 않아도됩니다. 관리자는 항상 앱을 실행 해 볼 수 있습니다. 한 가지 살펴볼 수있는 것은 System.Security.Principal.WindowsIdentity.GetCurrent()입니다. 현재 실행중인 사용자를 알려주는 이름입니다. – fyjham

+0

UAC없이 시도했지만, stilll은 작동하지 않습니다. 앱에서 현재 사용자를 확인했는데 사용중인 사용자와 동일합니다. 그런데 매핑 된 드라이브는 연결이 끊어졌습니다. 나는 그것이 어떤 차이를 의미해야한다고 생각하지 않지만 어쩌면 도움이 될 것입니다. – Zolka

8

좋아, 비스타에서 분리 된 드라이브를 얻는 방법을 알아 냈다. 쉬운 일이 아닙니다, 그것은하지만 행할 :

  • WNetOpenEnum
  • WNetEnumResource
  • WNetCloseEnum

그 :

먼저, 다음 WinAPI를 기능의 PInvoke를 정의해야합니다 구조체와 일부 enum을 필요로합니다.

그런 다음 여러 번 호출해야하며 마지막에는 목록이 표시됩니다. 당신은 WNetResource()를 호출 할 수있어

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

, 당신은 드라이브의 목록을 다시 얻을 것이다 : 는 여기가 긴, 조심, 코드입니다. (및 케이크 :-))

관련 문제