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

标签 c# wmi rdp

我正在尝试获取当前 rdp session 有权访问的所有驱动器的列表。这将包括我们提供给他们的驱动器以及他们从本地计算机共享的驱动器。我尝试使用 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?

最佳答案

我能够通过结合这两个网站的信息来获取 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绑定(bind):

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

关于c# - 获取驱动器列表,包括共享 RDP 驱动器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26685823/

相关文章:

c# - 如何获取远程机器上正在运行的进程的描述?

c# - 使用 C# 关闭打开的文件

asp.net - 如何解码 RDP 服务器的远程资源 URL (webfeed.aspx) 中返回的数据?

c# - 什么可以替代 MSTest 中的 [TearDown] 和 [SetUp]?

c# - 未创建日志文件?

c# - 在 Visual Studio Express 中计算方法执行时间(没有可用的探查器)?

windows - 如何检查 session 是否在 Windows 终端服务器中被隐藏

c# - 清除返回堆栈导航 Windows 10

c# - 如何在 .net 中为网络适配器设置 dns 搜索后缀?

c++ - 检查 Windows 机器是否可以充当 RDP 连接中的主机