You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Windows文件管理器开发:程序化访问LAN共享文件与设备

解决方案

一、枚举局域网内的网络设备/机器名

使用Windows原生API WNetEnumResource 实现网络资源枚举,比PowerShell命令更稳定可靠,以下是C#示例代码:

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

public class NetworkBrowser
{
    [DllImport("mpr.dll")]
    private static extern int WNetOpenEnum(int dwScope, int dwType, int dwUsage, IntPtr lpNetResource, out IntPtr lphEnum);

    [DllImport("mpr.dll")]
    private static extern int WNetEnumResource(IntPtr hEnum, ref int lpcCount, IntPtr lpBuffer, ref int lpBufferSize);

    [DllImport("mpr.dll")]
    private static extern int WNetCloseEnum(IntPtr hEnum);

    private const int RESOURCE_GLOBALNET = 0x00000002;
    private const int RESOURCETYPE_DISK = 0x00000001;
    private const int RESOURCEUSAGE_CONTAINER = 0x00000002;

    public static List<string> GetNetworkComputers()
    {
        List<string> computers = new List<string>();
        IntPtr hEnum = IntPtr.Zero;
        try
        {
            int result = WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_DISK, RESOURCEUSAGE_CONTAINER, IntPtr.Zero, out hEnum);
            if (result != 0) return computers;

            int bufferSize = 16384;
            IntPtr buffer = Marshal.AllocHGlobal(bufferSize);
            try
            {
                int entriesRead;
                do
                {
                    entriesRead = 0;
                    result = WNetEnumResource(hEnum, ref entriesRead, buffer, ref bufferSize);
                    if (result == 0 && entriesRead > 0)
                    {
                        IntPtr current = buffer;
                        for (int i = 0; i < entriesRead; i++)
                        {
                            NETRESOURCE nr = (NETRESOURCE)Marshal.PtrToStructure(current, typeof(NETRESOURCE));
                            if (nr.dwDisplayType == 3) // 3代表网络计算机节点
                            {
                                string computerName = nr.lpRemoteName?.TrimStart('\\');
                                if (!string.IsNullOrEmpty(computerName))
                                {
                                    computers.Add(computerName);
                                }
                            }
                            current += Marshal.SizeOf(nr);
                        }
                    }
                } while (result == 0);
            }
            finally
            {
                Marshal.FreeHGlobal(buffer);
            }
        }
        finally
        {
            if (hEnum != IntPtr.Zero)
            {
                WNetCloseEnum(hEnum);
            }
        }
        return computers;
    }

    [StructLayout(LayoutKind.Sequential)]
    private struct NETRESOURCE
    {
        public int dwScope;
        public int dwType;
        public int dwDisplayType;
        public int dwUsage;
        public string lpLocalName;
        public string lpRemoteName;
        public string lpComment;
        public string lpProvider;
    }
}

调用示例:

var lanComputers = NetworkBrowser.GetNetworkComputers();

二、获取指定机器的共享文件夹

通过WMI的Win32_Share类查询目标机器的磁盘共享,需引用System.Management程序集:

using System.Management;
using System.Collections.Generic;

public static List<string> GetMachineShares(string computerName)
{
    List<string> sharePaths = new List<string>();
    try
    {
        var scope = new ManagementScope($"\\\\{computerName}\\root\\cimv2");
        scope.Connect();
        
        var query = new ObjectQuery("SELECT * FROM Win32_Share WHERE Type = 0"); // Type=0表示磁盘类共享
        var searcher = new ManagementObjectSearcher(scope, query);
        
        foreach (ManagementObject share in searcher.Get())
        {
            string shareName = share["Name"].ToString();
            sharePaths.Add($"\\\\{computerName}\\{shareName}");
        }
    }
    catch (Exception ex)
    {
        // 捕获机器不可达、权限不足等异常
        Console.WriteLine($"获取共享失败: {ex.Message}");
    }
    return sharePaths;
}

调用示例:

var sharedFolders = GetMachineShares("DESKTOP-ABC123");

三、遍历共享目录的文件/文件夹

拿到UNC路径后,直接使用System.IO的常规API即可遍历,和本地文件操作逻辑一致:

using System.IO;

public static void TraverseShareDirectory(string uncPath)
{
    try
    {
        // 遍历子目录
        foreach (string dir in Directory.GetDirectories(uncPath))
        {
            Console.WriteLine($"目录: {dir}");
            TraverseShareDirectory(dir); // 递归遍历深层目录
        }
        
        // 遍历文件
        foreach (string file in Directory.GetFiles(uncPath))
        {
            Console.WriteLine($"文件: {file}");
        }
    }
    catch (UnauthorizedAccessException)
    {
        Console.WriteLine($"无权限访问路径: {uncPath}");
    }
    catch (DirectoryNotFoundException)
    {
        Console.WriteLine($"路径不存在: {uncPath}");
    }
}

关键注意事项

  • 网络发现开关:确保Windows系统的「网络发现」功能已启用,否则可能无法枚举到局域网内的机器。
  • 权限处理:访问需要验证的共享时,可使用WNetAddConnection2 API提前建立带用户名密码的连接,避免权限异常。
  • 异常捕获:枚举和遍历过程中必须处理机器离线、权限不足、路径不存在等异常,保证程序稳定性。

内容的提问来源于stack exchange,提问作者Zmuffin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 09:50:17