C# 中无法列出映射的网络驱动器

发布于 2024-08-14 18:56:36 字数 957 浏览 2 评论 0原文

我试图列出应用程序中的所有本地驱动器,并且 DriveInfo.GetDrives 返回本地驱动器号,并且我也需要映射的驱动器。

目前我有: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。该应用程序在本地计算机上运行,​​并且也是使用 Visual Studio 2008 在这里构建的。

我发布了我使用的内容,但它是如此简单,不可能是我做错了什么:

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

结果: C:\ D:\ E:\ 法:\ G:\ 按任意键继续。 。 。

我怎样才能让它发挥作用?

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.

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.

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.

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?

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

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

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

How can I make it work?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

潇烟暮雨 2024-08-21 18:56:36

好的,我找到了如何在 Vista 上获取断开连接的驱动器。这并不容易,但它是可行的:

首先,您需要以下 WinAPI 函数的 pInvoke 定义:

  • 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(),然后您将返回驱动器列表。 (和蛋糕:-))

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

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

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

静水深流 2024-08-21 18:56:36

Environment.GetLogicalDrives()DriveInfo.GetDrives() 都返回了我的所有联网驱动器。

您的应用程序是否以其他用户身份运行(例如 asp.net 网站)?如果是,驱动器实际上是为该用户映射的吗?您可能会发现驱动器已为您映射,但实际上并未为您的应用程序运行时的用户映射。

Environment.GetLogicalDrives() and DriveInfo.GetDrives() both returned all my networked drives.

Is your application running as a different user (For example an asp.net website)? If it is, are the drives actually mapped for that user? You might find that the drives are mapped for you but they aren't actually mapped for the user your application is running as.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文