Подключенные сетевые диски не могут быть перечислены в C#

Я пытаюсь перечислить все локальные диски в своем приложении, и DriveInfo.GetDrives отдайте локальные буквы дисков, и мне нужны сетевые диски также.

В настоящее время я имею: C:, D:, и G: (ЖЕСТКИЙ ДИСК), E: и F: (CD) и S: и Z: (подключенные сетевые диски). (Да, они все видимы в Windows Explorer, и в общем Командующем также.), Но только C, D, E, F, G получены программно.

Я также попробовал Environment.GetLogicalDrives(), GetLogicalDriveStrings (pInvoke), FindFirstVolume и FindNextVolumen (pInvoke). Я пытался найти список сетевого диска в реестре. Ничто не работает, только жесткий диск и буквы CD получены.

Нет никакого прибытия исключения, никакая ошибка, обозначенная в прямых вызовах WinAPI, и теперь я застреваю. Это - некоторая настройка безопасности? Везде я смотрю, люди говорят что DriveInfo.GetDrives должен отдать сетевые диски. Это действительно верно?

Я использую Vista Домой Pro. Приложение работает от локальной машины, и это создается здесь также с Visual Studio 2008.

Я отправляю то, что я использовал, но это столь просто, не может иметь место, что я делаю что-то не так:

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

Результат: C:\ D:\E:\ F:\G:\ Press any key to continue...

Как я могу заставить его работать?

9
задан Zolka 11 December 2012 в 18:21
поделиться

2 ответа

Хорошо, я узнал, как получить отключенные диски в Vista. Это непросто, но выполнимо:

Во-первых, вам понадобится определение pInvoke следующих функций WinAPI:

  • WNetOpenEnum
  • WNetEnumResource
  • WNetCloseEnum

, а им нужна структура и некоторые перечисления как хорошо.

Затем вам нужно позвонить им несколько раз, и в конце вы получите список. Вот код, будьте осторожны, он длинный:

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

Вам нужно вызвать WNetResource (), и вы вернете список дисков. (и торт: -))

8
ответ дан 4 December 2019 в 15:21
поделиться

Environment.GetLogicalDrives () и DriveInfo.GetDrives () оба вернули все мои сетевые диски.

Ваше приложение запущено от имени другого пользователя (для пример веб-сайта asp.net)? Если да, то действительно ли диски подключены для этого пользователя? Вы можете обнаружить, что диски отображаются для вас, но на самом деле они не привязаны к пользователю, от имени которого работает ваше приложение.

5
ответ дан 4 December 2019 в 15:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: