Easy SFTP (Secure FTP) With C# and PSFTP

There are a number of .Net projects out there that allow you to use SFTP, but all of them I’ve tried are confusing or just don’t work.  The makers of PuTTY (an open source telnet/SSH/etc client) made a command line app (PSFTP download it here) specifically for people scripting SFTP.  Essentially it’s a command line app that takes a few arguements and can run a batch script.  The code below is a basic introduction to using it with your C# apps.  It generates the batch script automatically and runs PSFTP as a Process.  For more uses of PSFTP, read the documetation here.

Two catches:

1)  You have to accept the SSH certificate from the server you’re trying to connect to prior to running the script below or it WILL NOT work, to do this, just use PuTTY or other SSH clients to connect to the server and accept its’ certificate;

2)  This is ONLY for SFTP.  For regular FTP check out my other post here.

using System;

using System.Collections.Generic;

using System.Diagnostics;

using System.IO;

using System.Linq;

using System.Text;

namespace SFTP

{

class Program

{

static void Main(string[] args)

{

string[] remoteFiles = new string[]

{

@”/etc/remote-file1.txt”,

@”/etc/remote-file2.txt”,

@”/etc/remote-file3.txt”

};

string[] localFiles = new string[]

{

@”C:\local-file1.txt”,

@”C:\local-file2.txt”,

@”C:\local-file3.txt”

};

string[] commands = new string[]

{

@”cd /home”,

@”dir”

};

PSFTP PsftpClient = new PSFTP(@”10.10.10.10″, @”root”, @”password”);

PsftpClient.Get(remoteFiles, localFiles);

PsftpClient.Put(remoteFiles, localFiles);

PsftpClient.SendCommands(commands);

Console.WriteLine(PsftpClient.Outputs);

PsftpClient = null;

}

}

class PSFTP

{

private string _Host;

private string _User;

private string _Password;

private string _BatchFilePath = @”C:\batch.txt”;

private string _PsftpPath = @”C:\psftp”; // Change this to the location of the PSTFP app.  Do not include the ‘.exe’ file extension.

public string Outputs = “”; // Stores the outputs and errors of PSFTP

/* Object Constructor for standard usage */

public PSFTP(string Host, string User, string Password)

{

_Host = Host;

_User = User;

_Password = Password;

}

/* Retrieve files from the server */

public void Get(string[] Remote, string[] Local)

{

/* Format the commands */

string[] Commands = new string[Remote.Count()];

for (int i = 0; i < Remote.Count(); i++)

{

Commands[i] = @”get “ + Remote[i] + @” “ + Local[i];

}

GenerateBatchFile(Commands);

Run();

return;

}

        /* Send files from your computer to the server */

public void Put(string[] Remote, string[] Local)

{

            /* Format the commands */

string[] Commands = new string[Remote.Count()];

for (int i = 0; i < Remote.Count(); i++)

{

Commands[i] = @”put “ + Remote[i] + @” “ + Local[i];

}

GenerateBatchFile(Commands);

Run();

return;

}

        /* Use this to send other SFTP commands (CD, DIR, etc.) */

public void SendCommands(string[] commands)

{

GenerateBatchFile(commands);

Run();

            return;

}

        /* Create a text file with a list of commands to be fed into PSFTP */

private void GenerateBatchFile(string[] Commands)

{

try

{

StreamWriter batchWriter = new StreamWriter(_BatchFilePath);

                /* Write each command to the batch file */

for (int i = 0; i < Commands.Count(); i++)

{

batchWriter.WriteLine(Commands[i]);

}

                /* Command to close the connection */

batchWriter.WriteLine(@”bye”);

batchWriter.Close();

}

catch (Exception ex) { Console.WriteLine(ex.ToString()); }

return;

}

        /* Run the commands, store the outputs */

private void Run()

{

            /* Execute PSFTP as a System.Diagnostics.Process using the supplied login info and generated batch file */

try

{

ProcessStartInfo PsftpStartInfo = new ProcessStartInfo(_PsftpPath, _User + @”@” + _Host + @” -pw “ + _Password + @” -batch -be -b “ + _BatchFilePath);

                /* Allows redirecting inputs/outputs of PSFTP to your app */

PsftpStartInfo.RedirectStandardInput = true;

PsftpStartInfo.RedirectStandardOutput = true;

PsftpStartInfo.RedirectStandardError = true;

PsftpStartInfo.UseShellExecute = false;

Process PsftpProcess = new Process();

PsftpProcess.StartInfo = PsftpStartInfo;

PsftpProcess.Start();

                /* Streams for capturing outputs and errors as well as taking ownership of the input */

StreamReader PsftpOutput = PsftpProcess.StandardOutput;

StreamReader PsftpError = PsftpProcess.StandardError;

StreamWriter PsftpInput = PsftpProcess.StandardInput;

while (!PsftpOutput.EndOfStream)

{

try

{

                        /* This is usefule for commands other than ‘put’ or ‘get’ and for catching errors. */

Outputs += PsftpOutput.ReadLine();

Outputs += PsftpError.ReadLine();

}

catch (Exception ex) { Console.WriteLine(ex.ToString()); }

}

PsftpOutput.Close();

PsftpError.Close();

PsftpInput.Close();

PsftpProcess.WaitForExit();

PsftpStartInfo = null;

PsftpProcess = null;

}

catch (Exception ex) { Console.WriteLine(ex.ToString()); }

            /* Delete the batch file */

try

{

File.Delete(_BatchFilePath);

}

catch (Exception ex) { Console.WriteLine(ex.ToString()); }

return;

}

}

}

Advertisements
Posted in Automation, C#, External Application, FTP, Process, PSFTP, PuTTY, SFTP

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: