获取本地网络服务器上所有 UNC 共享文件夹的列表

Posted

技术标签:

【中文标题】获取本地网络服务器上所有 UNC 共享文件夹的列表【英文标题】:Get a list of all UNC shared folders on a local network server 【发布时间】:2010-08-25 14:43:08 【问题描述】:

我正在尝试获取本地 Intranet 服务器上所有可用共享文件夹的列表。

System.IO.Directory.GetDirectories() 适用于\\myServer\myShare 之类的路径,但是对于\\myServer 之类的路径,我遇到了异常:

未处理的异常:System.ArgumentException:UNC 路径的格式应为 \server\share。

有没有办法获取服务器的所有共享文件夹列表?最终,我正在寻找一种可以根据给定路径处理这两种情况的方法 - 返回给定服务器的所有共享列表并返回给定网络共享文件夹的所有子目录的列表。

【问题讨论】:

Enumerating Network Shares with C#的可能重复 @kbrimington 这个 Q 要求远程,那个 Q 只要求本地。 @Richard:接受的答案也包括远程。 @kbrimington - 出于某种原因,我通过NetShareEnum 仅在本地...避免需要 P/Invoke。 @Richard:已接受答案中的 CodeProject 链接提供了“枚举本地和远程机器上的网络共享的类,并将本地文件路径转换为 ​​UNC 路径。” (强调补充)。 @ajay_whiz 的回答引用了同一篇文章。 【参考方案1】:

这是一种使用System.Management 的技术(添加对此程序集的引用):

using (ManagementClass shares = new ManagementClass(@"\\NameOfTheRemoteComputer\root\cimv2", "Win32_Share", new ObjectGetOptions())) 
    foreach (ManagementObject share in shares.GetInstances()) 
        Console.WriteLine(share["Name"]);
    

需要适当的权限。

【讨论】:

谢谢,布拉德利。您的技术可以很好地枚举我本地计算机上的共享,但是当我尝试访问本地网络上的服务器时,它给了我System.Management.ManagementException: Access denied 异常。同时,另一个解决方案(使用 P/Invoke)在同一台服务器上运行良好。 是的,我检查过了,你是对的。我认为 WMI 的功能远不止眼前所见——包括需要以某种方式使用 ConnectionOptions 和 ManagementScope 类才能访问远程计算机。我确信这是可能的,但在这个阶段我没有经验来描述如何做到这一点。 对我来说就像一个魅力(击中删除机器)。但是,我以自己的身份运行,并且我的用户在目标计算机上具有管理员权限。 这会很棒,但我收到错误 System.Runtime.InteropServices.COMException: 'The RPC server is unavailable. 看起来它与我无法控制的 Windows 防火墙设置有关。【参考方案2】:

我想这就是你要找的http://www.codeproject.com/KB/IP/networkshares.aspx

【讨论】:

谢谢,这对我有用。我最终编写了一个扩展 System.IO.Directory.GetDirectories() 的方法。它使用正则表达式来确定给出什么样的路径(//server/share 或只是 //server),然后分别调用 Directory.GetDirectories() 或 CodeProject 库。【参考方案3】:
    private DataTable GetSharedFolderAccessRule()
    
        DataTable DT = new DataTable();

        try
        
            DT.Columns.Add("ShareName");
            DT.Columns.Add("Caption");
            DT.Columns.Add("Path");
            DT.Columns.Add("Domain");
            DT.Columns.Add("User");
            DT.Columns.Add("AccessMask");
            DT.Columns.Add("AceType");

            ManagementScope Scope = new ManagementScope(@"\\.\root\cimv2");
            Scope.Connect();
            ObjectQuery Query = new ObjectQuery("SELECT * FROM Win32_LogicalShareSecuritySetting");
            ManagementObjectSearcher Searcher = new ManagementObjectSearcher(Scope, Query);
            ManagementObjectCollection QueryCollection = Searcher.Get();

            foreach (ManagementObject SharedFolder in QueryCollection)
            
                
                    String ShareName = (String) SharedFolder["Name"];
                    String Caption   = (String)SharedFolder["Caption"];
                    String LocalPath = String.Empty;
                    ManagementObjectSearcher Win32Share = new ManagementObjectSearcher("SELECT Path FROM Win32_share WHERE Name = '" + ShareName + "'");
                    foreach (ManagementObject ShareData in Win32Share.Get())
                    
                        LocalPath = (String) ShareData["Path"];
                    

                    ManagementBaseObject Method = SharedFolder.InvokeMethod("GetSecurityDescriptor", null, new InvokeMethodOptions());
                    ManagementBaseObject Descriptor = (ManagementBaseObject)Method["Descriptor"];
                    ManagementBaseObject[] DACL = (ManagementBaseObject[])Descriptor["DACL"];
                    foreach (ManagementBaseObject ACE in DACL)
                    
                        ManagementBaseObject Trustee = (ManagementBaseObject)ACE["Trustee"];

                        // Full Access = 2032127, Modify = 1245631, Read Write = 118009, Read Only = 1179817
                        DataRow Row = DT.NewRow();
                        Row["ShareName"]  = ShareName;
                        Row["Caption"]    = Caption;
                        Row["Path"]       = LocalPath;
                        Row["Domain"]     = (String) Trustee["Domain"];
                        Row["User"]       = (String) Trustee["Name"];
                        Row["AccessMask"] = (UInt32) ACE["AccessMask"];
                        Row["AceType"]    = (UInt32) ACE["AceType"];
                        DT.Rows.Add(Row);
                        DT.AcceptChanges();
                    
                
            
        
        catch (Exception ex) 
        
            MessageBox.Show(ex.StackTrace, ex.Message);
        

        return DT;
    

【讨论】:

以上是关于获取本地网络服务器上所有 UNC 共享文件夹的列表的主要内容,如果未能解决你的问题,请参考以下文章

本地计算机上文件夹的 UNC 路径

通过 unc 获取/设置 azure 文件的元数据

从FTP服务器获取文件并将其复制到UNC目录

IIS站点/虚拟目录中访问共享目录(UNC)以及建立后的应用程序的信任级别问题

在 C# 中将 UNC 路径转换为本地路径

无法访问 Powershell 远程会话中的 UNC 路径