映射的网络驱动器不能在C#中上市 [英] Mapped network drives cannot be listed in 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屋!