获取驱动器列表,包括共享RDP驱动器

时间:2014-11-01 02:57:27

标签: c# wmi rdp

我正在尝试获取当前rdp会话可以访问的所有驱动器的列表。这将包括我们提供给他们的驱动器以及他们从本地计算机共享的驱动器。我已经尝试使用WMI和DriveInfo来获取驱动器,但它似乎并没有返回共享驱动器。我注意到net use命令可以显示共享驱动器。

这是我尝试过的事情

        try
        {
            ManagementPath path = new ManagementPath()
            {
                NamespacePath = @"\\"+ clientName + @"\root\cimv2",
                Server = "127.0.0.1"
            };
            ManagementScope scope = new ManagementScope(path);
            SelectQuery query = new SelectQuery("Win32_LogicalDisk");

            using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query))
            using (ManagementObjectCollection results = searcher.Get())
            {
                List<ManagementObject> volume = results.Cast<ManagementObject>().ToList();

                foreach (var vol in volume)
                {
                    if (volume != null)
                    {

                    }
                }
            }
        }
        catch (Exception e)
        {

        }

有没有办法用C#以编程方式检索这些信息,如果WMI是这样的,我会怎么做?

1 个答案:

答案 0 :(得分:2)

我能够通过组合来自这两个网站的信息来获取TS客户端驱动器

http://www.44342.com/Windows-Terminal-Services-f1018-t1029-p1.htm http://www.codeproject.com/Articles/6235/Enumerating-Network-Resources

示例实现:

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;

namespace ServerEnumDemo
{
    public sealed class TsClientSharesProvider : IDisposable
    {
        private IntPtr handle = IntPtr.Zero;
        private IntPtr buffer = IntPtr.Zero;
        private IList<string> result;
        public IEnumerable<string> GetUncPaths()
        {
            if (result != null)
            {
                return result;
            }
            result = new List<string>();
            EnumerateTsclientShares(result, new Win32.NETRESOURCE());
            return result;
        }
        public void Dispose()
        {
            if (handle != IntPtr.Zero)
            {
                Win32.WNetCloseEnum(handle);
                handle = IntPtr.Zero;
            }
            if (buffer != IntPtr.Zero)
            {
                Marshal.FreeHGlobal(buffer);
                buffer = IntPtr.Zero;
            }
        }

        private void EnumerateTsclientShares(ICollection<string> result, Win32.NETRESOURCE pRsrc)
        {
            uint bufferSize = 16384;
            buffer = Marshal.AllocHGlobal((int)bufferSize);
            uint cEntries = 1;


            var returncode = Win32.WNetOpenEnum(Win32.ResourceScope.RESOURCE_GLOBALNET, Win32.ResourceType.RESOURCETYPE_DISK,
                Win32.ResourceUsage.RESOURCEUSAGE_ALL, pRsrc, out handle);

            if (returncode != Win32.ErrorCodes.NO_ERROR)
            {
                throw new Exception("Could not enumerate network shares");
            }

            do
            {
                returncode = Win32.WNetEnumResource(handle, ref cEntries, buffer, ref bufferSize);

                if (returncode == Win32.ErrorCodes.NO_ERROR)
                {
                    Marshal.PtrToStructure(buffer, pRsrc);
                    if ((pRsrc.dwUsage == Win32.ResourceUsage.RESOURCEUSAGE_CONNECTABLE)
                        && pRsrc.lpLocalName.Contains("tsclient"))
                    {
                        result.Add(pRsrc.lpLocalName);
                    }

                    if ((pRsrc.dwUsage & Win32.ResourceUsage.RESOURCEUSAGE_CONTAINER) ==
                        Win32.ResourceUsage.RESOURCEUSAGE_CONTAINER)
                    {
                        EnumerateTsclientShares(result, pRsrc);
                    }
                }
                else if (returncode != Win32.ErrorCodes.ERROR_NO_MORE_ITEMS)
                {
                    Console.WriteLine("ERROR " + returncode);
                }
            } while (returncode != Win32.ErrorCodes.ERROR_NO_MORE_ITEMS);
        }
    }
}

相应的Win32绑定:

using System;
using System.Runtime.InteropServices;

namespace ServerEnumDemo
{
    public static class Win32
    {
        [DllImport("Mpr.dll", EntryPoint = "WNetOpenEnumA", CallingConvention = CallingConvention.Winapi)]
        internal static extern ErrorCodes WNetOpenEnum(ResourceScope dwScope, ResourceType dwType, ResourceUsage dwUsage,
            NETRESOURCE p, out IntPtr lphEnum);

        [DllImport("Mpr.dll", EntryPoint = "WNetCloseEnum", CallingConvention = CallingConvention.Winapi)]
        internal static extern ErrorCodes WNetCloseEnum(IntPtr hEnum);

        [DllImport("Mpr.dll", EntryPoint = "WNetEnumResourceA", CallingConvention = CallingConvention.Winapi)]
        internal static extern ErrorCodes WNetEnumResource(IntPtr hEnum, ref uint lpcCount, IntPtr buffer,
            ref uint lpBufferSize);

        public enum ResourceDisplayType
        {
            RESOURCEDISPLAYTYPE_GENERIC,
            RESOURCEDISPLAYTYPE_DOMAIN,
            RESOURCEDISPLAYTYPE_SERVER,
            RESOURCEDISPLAYTYPE_SHARE,
            RESOURCEDISPLAYTYPE_FILE,
            RESOURCEDISPLAYTYPE_GROUP,
            RESOURCEDISPLAYTYPE_NETWORK,
            RESOURCEDISPLAYTYPE_ROOT,
            RESOURCEDISPLAYTYPE_SHAREADMIN,
            RESOURCEDISPLAYTYPE_DIRECTORY,
            RESOURCEDISPLAYTYPE_TREE,
            RESOURCEDISPLAYTYPE_NDSCONTAINER
        };

        [StructLayout(LayoutKind.Sequential)]
        internal class NETRESOURCE
        {
            public ResourceDisplayType dwDisplayType = 0;
            public ResourceScope dwScope = 0;
            public ResourceType dwType = 0;
            public ResourceUsage dwUsage = 0;
            public string lpComment = null;
            public string lpLocalName = null;
            public string lpProvider = null;
            public string lpRemoteName = null;
        }

        public enum ResourceUsage
        {
            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 ResourceScope
        {
            RESOURCE_CONNECTED = 1,
            RESOURCE_GLOBALNET,
            RESOURCE_REMEMBERED,
            RESOURCE_RECENT,
            RESOURCE_CONTEXT
        };

        public enum ResourceType
        {
            RESOURCETYPE_ANY,
            RESOURCETYPE_DISK,
            RESOURCETYPE_PRINT,
            RESOURCETYPE_RESERVED
        };

        internal enum ErrorCodes
        {
            NO_ERROR = 0,
            ERROR_NO_MORE_ITEMS = 259
        }
    }
}