Copying or moving a remote file using SSH.NET with C#

user1451111 picture user1451111 · Dec 9, 2015 · Viewed 45.5k times · Source

I know that I can upload and download files from/to a SFTP server using SftpClient class of SSH.NET library but I am not sure how can this class be used for copying or moving a remote file on the SFTP server. I also did not find relevant material on internet. How can i copy or move a remote file from directory A to directory B, using SSH.NET library and C#.

Update: I also tried experimenting with SshClient class using the below code but it does nothing, neither any error nor any exception.

ConnectionInfo ConnNfo = new ConnectionInfo("FTPHost", 22, "FTPUser",
new AuthenticationMethod[]{

   // Pasword based Authentication
   new PasswordAuthenticationMethod("FTPUser","FTPPass")
   }                
   );

using (var ssh = new SshClient(ConnNfo))
{
    ssh.Connect();                
    if (ssh.IsConnected)
    {                    
         string comm = "pwd";
         using (var cmd = ssh.CreateCommand(comm))
         {
            var returned = cmd.Execute();
            var output = cmd.Result;
            var err = cmd.Error;
            var stat = cmd.ExitStatus;
         }
     }
   ssh.Disconnect();
}

On Visual Studio console, i get the below output.

*SshNet.Logging Verbose: 1 : SendMessage to server 'ChannelRequestMessage': 'SSH_MSG_CHANNEL_REQUEST : #152199'.

SshNet.Logging Verbose: 1 : ReceiveMessage from server: 'ChannelFailureMessage': 'SSH_MSG_CHANNEL_FAILURE : #0'.*

Answer

LogicFirst picture LogicFirst · Aug 29, 2016

Moving a remote File can be done using SSH.NET library. Available here: https://github.com/sshnet/SSH.NET

Here is sample code to move first file from one source folder to another. Set private variables in the class according to the FTP set up.

using System;
using System.Linq;
using System.Collections.Generic;
using Renci.SshNet;
using Renci.SshNet.Sftp;
using System.IO;
using System.Configuration;
using System.IO.Compression;

public class RemoteFileOperations
{
    private string ftpPathSrcFolder = "/Path/Source/";//path should end with /
    private string ftpPathDestFolder = "/Path/Archive/";//path should end with /
    private string ftpServerIP = "Target IP";
    private int ftpPortNumber = 80;//change to appropriate port number
    private string ftpUserID = "FTP USer Name";//
    private string ftpPassword = "FTP Password";
    /// <summary>
    /// Move first file from one source folder to another. 
    /// Note: Modify code and add a for loop to move all files of the folder
    /// </summary>
    public void MoveFolderToArchive()
    {
        using (SftpClient sftp = new SftpClient(ftpServerIP, ftpPortNumber, ftpUserID, ftpPassword))
        {
            SftpFile eachRemoteFile = sftp.ListDirectory(ftpPathSrcFolder).First();//Get first file in the Directory            
            if(eachRemoteFile.IsRegularFile)//Move only file
            {
                bool eachFileExistsInArchive = CheckIfRemoteFileExists(sftp, ftpPathDestFolder, eachRemoteFile.Name);

                //MoveTo will result in error if filename alredy exists in the target folder. Prevent that error by cheking if File name exists
                string eachFileNameInArchive = eachRemoteFile.Name;

                if (eachFileExistsInArchive)
                {
                    eachFileNameInArchive = eachFileNameInArchive + "_" + DateTime.Now.ToString("MMddyyyy_HHmmss");//Change file name if the file already exists
                }
                eachRemoteFile.MoveTo(ftpPathDestFolder + eachFileNameInArchive);
            }           
        }
    }

    /// <summary>
    /// Checks if Remote folder contains the given file name
    /// </summary>
    public bool CheckIfRemoteFileExists(SftpClient sftpClient, string remoteFolderName, string remotefileName)
    {
        bool isFileExists = sftpClient
                            .ListDirectory(remoteFolderName)
                            .Any(
                                    f => f.IsRegularFile &&
                                    f.Name.ToLower() == remotefileName.ToLower()
                                );
        return isFileExists;
    }

}