映射的网络驱动器不能在C#中上市 [英] Mapped network drives cannot be listed in C#

查看:155
本文介绍了映射的网络驱动器不能在C#中上市的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想列出所有本地驱动器在我的应用程序,而 DriveInfo.GetDrives 回馈本地驱动器字母,我需要映射驱动器了。

I am trying to list all local drives in my application, and DriveInfo.GetDrives give back the local drive letters, and I need the mapped drives too.

目前我有:C:,D:和G:(HDD),E:和F:(CD)和S:和Z:(映射网络驱动器)。 (是的,他们都是可见的在Windows资源管理器中,并在总指挥官了。)
,而只有C,D,E,F,G编程方式检索。

Currently I have: C:, D:, and G: (HDD), E: and F: (CD), and S: and Z: (mapped network drives). (Yes, they are all visible in Windows Explorer, and in Total Commander too.) But only C, D, E, F, G are retrieved programmatically.

我也试过 Environment.GetLogicalDrives() GetLogicalDriveStrings(PInvoke的) FindFirstVolume FindNextVolumen (PInvoke的)。我试图在注册表中找到映射驱动器列表。实在不行,只有硬盘和CD字母retreived。

I also tried Environment.GetLogicalDrives(), GetLogicalDriveStrings (pInvoke), FindFirstVolume and FindNextVolumen (pInvoke). I tried to find the mapped drive list in the registry. Nothing works, only the HDD and CD letters are retreived.

有没有任何异常出现,没有在直接调用WinAPI的错误指示,现在我卡住了。它是某种安全设置的?我到处看,人说 DriveInfo.GetDrives 应该给后面的映射驱动器。难道是真的吗?

There isn't any exception coming, no error indicated in the direct WinAPI calls, and now I am stuck. Is it some kind of security setting? Everywhere I look, the people say that the DriveInfo.GetDrives should give back the mapped drives. Is it really true?

我使用Vista家庭专业版。该应用程序从本地机器上运行,并且它也建在这里用Visual 工作室  2008

I am using Vista Home Pro. The application is running from the local machine, and it is built here too with Visual Studio 2008.

我后我用的东西,但它是如此简单,它不能说我做错事的情况:在System.IO.DriveInfo.GetDrives

I post what I used, but it is so simple, it cannot be the case that I do something wrong:

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



结果:
C:\
D:\
é:\
F:\
G:\
按任意键继续。 。

Result: C:\ D:\ E:\ F:\ G:\ Press any key to continue . . .

我怎样才能使它工作?

推荐答案

确定,我发现了如何获得在Vista上断开驱动器。不容易,但它是可行的:

OK, I found out how to get the disconnected drives on Vista. Not easy, but it is doable:

首先,你需要以下WinAPI的函数的PInvoke定义:

First, you'll need the pInvoke definition of the following WinAPI functions:


  • WNetOpenEnum

  • WNetEnumResource

  • WNetCloseEnum

和那些需要一个结构和一些枚举为好。

and those need a struct and some enums as well.

然后,你需要那些多次打电话,并在最后,你会得到列表。
下面是代码,要小心,它长:

Then you need to call those multiple times, and at the end, you get the list. Here is the code, beware, it is long:

    [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(),你会回来驱动器的列表。 (和蛋糕: - ))

You've got to call the WNetResource(), and you will get back the list of drives. (and cake :-))

这篇关于映射的网络驱动器不能在C#中上市的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆