C#访问共享目录总结

在各种业务需求中,我们经常要访问一个在网络中的目录,读取其中的文件或者是在其目录中创建文件,在.Net中我们主要使用mpr.dll中的WNetAddConnection2和WNetCancelConnection2来实现,下面是代码引入。

        [DllImport("mpr.dll")]
        private static extern int WNetAddConnection2(NetResource netResource,
            string password, string username, int flags);

        [DllImport("mpr.dll")]
        private static extern int WNetCancelConnection2(string name, int flags,
            bool force);

在上述代码中使用到的NetResource 我们可以定义如下:

var netResource = new NetResource
            {
                Scope = ResourceScope.GlobalNetwork,
                ResourceType = ResourceType.Disk,
                DisplayType = ResourceDisplayType.Share,
                RemoteName = networkName
            };

参数RemoteName就是远程网络路径。比如@"\\10.5.5.5\Public\Test"。

using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Net;

namespace Phoenix.Modules.Common.Service.Uploads
{
    public class ConnectToSharedFolder : IDisposable
    {
        readonly string _networkName;

        public ConnectToSharedFolder(string networkName, NetworkCredential credentials)
        {
            _networkName = networkName;

            var netResource = new NetResource
            {
                Scope = ResourceScope.GlobalNetwork,
                ResourceType = ResourceType.Disk,
                DisplayType = ResourceDisplayType.Share,
                RemoteName = networkName
            };

            var userName = string.IsNullOrEmpty(credentials.Domain)
                ? credentials.UserName
                : $@"{credentials.Domain}\{credentials.UserName}";

            var result = WNetAddConnection2(
                netResource,
                credentials.Password,
                userName,
                0);

            if (result != 0)
            {
                throw new Win32Exception(result, "Error connecting to remote share");
            }
        }

        ~ConnectToSharedFolder()
        {
            Dispose(false);
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool disposing)
        {
            WNetCancelConnection2(_networkName, 0, true);
        }

        [DllImport("mpr.dll")]
        private static extern int WNetAddConnection2(NetResource netResource,
            string password, string username, int flags);

        [DllImport("mpr.dll")]
        private static extern int WNetCancelConnection2(string name, int flags,
            bool force);

        [StructLayout(LayoutKind.Sequential)]
        public class NetResource
        {
            public ResourceScope Scope;
            public ResourceType ResourceType;
            public ResourceDisplayType DisplayType;
            public int Usage;
            public string LocalName;
            public string RemoteName;
            public string Comment;
            public string Provider;
        }

        public enum ResourceScope : int
        {
            Connected = 1,
            GlobalNetwork,
            Remembered,
            Recent,
            Context
        };

        public enum ResourceType : int
        {
            Any = 0,
            Disk = 1,
            Print = 2,
            Reserved = 8,
        }

        public enum ResourceDisplayType : int
        {
            Generic = 0x0,
            Domain = 0x01,
            Server = 0x02,
            Share = 0x03,
            File = 0x04,
            Group = 0x05,
            Network = 0x06,
            Root = 0x07,
            Shareadmin = 0x08,
            Directory = 0x09,
            Tree = 0x0a,
            Ndscontainer = 0x0b
        }
    }
}
ConnectToSharedFolder

引入ConnectToSharedFolder、NetResource、ResourceScope,就可以直接添加代码写入文件了。

using Phoenix.Modules.Common.Service.Uploads;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp4_networkDic
{
    class Program
    {
        public static string networkPath = @"\\10.5.5.5\test";

        static NetworkCredential credentials = new NetworkCredential(@"test", "May");

        public static string myNetworkPath = string.Empty;

        static void Main(string[] args)
        {
            string filename = "test.txt";
            FileUpload(filename);
            Console.ReadKey();
        }

        public static void  FileUpload(string UploadURL)
        {
            try
            {
                using (new ConnectToSharedFolder(networkPath, credentials))
                {
                    var fileList = Directory.GetDirectories(networkPath);
                    foreach (var item in fileList) { if (item.Contains("{ClientDocument}")) { myNetworkPath = item; } }
                    myNetworkPath = networkPath+@"\" + UploadURL;

                    using (FileStream fileStream = File.Create(myNetworkPath))
                    {
                        var file = System.Text.Encoding.UTF8.GetBytes("this is a test");
                        fileStream.Write(file, 0, file.Length);
                        fileStream.Flush();
                        fileStream.Close();
                    }
                }
            }
            catch (Exception ex)
            {
            }
            
        }
    }

}
测试代码

 

这样就可以访问和读取网络中的路径了,在测试中一直遇到在调用wnetaddconnection2方法的时候返回error 53的错误,看代码中也是没有错误,直接访问所用的测试目标网络文件也是可以的,然后再google一搜,就是我们在传递网络目标文件路径的时候后面不能有“\”,把“\”去掉然后再访问就没有问题了。

原文链接https://social.msdn.microsoft.com/Forums/windows/en-US/5f8224d4-c36a-4051-a8e5-7b2e4d817986/wnetaddconnection2-fails-with-error-code-53?forum=peertopeer。

 

posted @ 2021-11-09 14:37  VarForrest  阅读(1039)  评论(0编辑  收藏  举报