Search code examples
c#smb

Create file , get file and delete with SMB protocol


Create file, create folder, get file, delete file, list folder and rename file. This are all methods that I need to implement using SMB protocol.

I already have same functionality implemented with FTP protocol. For example:

private void FtpCreateFolder(string ftpAddress, string ftpUName, string ftpPWord)
    {
            WebRequest ftpRequest = WebRequest.Create("ftp://" + ftpAddress + "/AUTO_TEST_FOLDER");
            ftpRequest.Method = WebRequestMethods.Ftp.MakeDirectory;
            ftpRequest.Credentials = new NetworkCredential(ftpUName, ftpPWord);
    }

What library should I use to implement same methods with SMB protocol ?


Solution

  • I post solution. You can see more details.

    First create network connection:

        [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 class NetworkConnection : IDisposable
        {
            private string _networkName;
            private NetworkCredential _credentials;
    
            public NetworkConnection(string networkName, NetworkCredential credentials)
            {
                _networkName = networkName;
                _credentials = credentials;
            }
    
            public int Connect()
            {
                var netResource = new NetResource()
                {
                    Scope = ResourceScope.GlobalNetwork,
                    ResourceType = ResourceType.Disk,
                    DisplayType = ResourceDisplaytype.Share,
                    RemoteName = _networkName
                };
    
                var userName = string.IsNullOrEmpty(_credentials.Domain)
                    ? _credentials.UserName
                    : string.Format(@"{0}\{1}", _credentials.Domain, _credentials.UserName);
    
                var result = WNetAddConnection2(
                    netResource,
                    _credentials.Password,
                    userName,
                    0);
                return result;
            }
    
            ~NetworkConnection()
            {
                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);
        }
    }
    
    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
    };
    

    How to use Network connection:

     public class SmbFileContainer
        {
            private readonly NetworkCredential networkCredential;
            // Path to shared folder:
            private readonly string networkPath;
    
            public SmbFileContainer()
            {
                this.networkPath = @"\\MY_PC\SharedFolder";
                var userName = "Bob";
                var password = "123";
                var domain = "";
                networkCredential = new NetworkCredential(userName, password, domain);
            }
    
            public bool IsValidConnection()
            {
                using (var network = new NetworkConnection($"{networkPath}", networkCredential))
                {
                    var result = network.Connect();
                    return result == 0;
                }
            }
    
            public void CreateFile(string targetFile, string content)
            {
                using (var network = new NetworkConnection(networkPath, networkCredential))
                {
                    network.Connect();
                    var file = Path.Combine(this.networkPath, targetFile);
                    if (!File.Exists(file))
                    {
                        using (File.Create(file)) { };
                        using (StreamWriter sw = File.CreateText(file))
                        {
                            sw.WriteLine(content);
                        }
                    }
                }
            }
        }
    

    Test:

    static void Main(string[] args)
            {
                var smb = new SmbFileContainer();
    
                if (smb.IsValidConnection())
                {
                    smb.CreateFile("testFile.txt", "Hello World");
                }
    
            }