Click here to Skip to main content
12,300,021 members (52,054 online)
Click here to Skip to main content
Add your own
alternative version

Tagged as

Stats

65.5K views
25 bookmarked
Posted

sFTP and .NET

, 6 May 2014 CPOL
Rate this:
Please Sign up or sign in to vote.
How to achieve sFTP using .NET

Introduction

With the release of the new .NET 4.5 framework; I was pretty stoked at diving in and seeing all the new functionality available. One of the most talked about features was the improvements to the Asynchronous Programming model (previous versions used TPL). This is great, and will get used a lot by developers. But, one of the features I (and few others) were looking for was the support for sFTP built-in the .NET framework. Sadly, it was not found.

After some rigorous searching for a .NET wrapper to handle secure shell transmissions, I came across WinSCP; which is not only free (the best part!), but also included a wrapper to use in code. Jackpot!

Using WinSCP is really straightforward. The developer has done an excellent job in documenting, an active community of users, and really just putting together a tool that interfaces well with .NET.

Background

Some knowledge might be helpful on how currently .NET handles FTP and a quick read on FtpWebRequest and FtpWebResponse would be helpful, but not necessary.

Remember, there are a number of ways to transfer files using FTP and sFTP. But this particular scenario needed to transfer files via code (C#). Oh, and as an aside, the 's' in front of 'sFTP' does not mean 'secure' (literally), but instead stands for 'SSH' - secure shell.

Another note, in order to use WinSCP, you will need the SSHHostKeyFingerprint for the designated server you are trying to connect to. If you are not sure about how to obtain this, you can always ask your administrator for this key. This key is not top secret information and should be available to you publicly.

Or, similarly, you could install a FTP client that also handles SSH transmissions and grab the SSH Host Key Fingerprint via the options menu for the tools that have been tested below:

For WS_FTP:

  1. Download and install WS_FTP (trial version will work as well).
  2. Connect to your sFTP site via the hostname, username, and password.
  3. When prompted to examine the "Untrusted SSH Host Key", select "Trust this key"
  4. If you ever need to recover the SSH Host Key, you can go to Tools -> Options -> SSH (On the left) -> Trusted Hosts

For WinSCP:

  1. Download and install WinSCP.
  2. Connect to your sFTP site using your hostname, username, and password.
  3. Once connected, you can retrieve the SSH host key fingerprint by going into "Commands" -> "Server/Protocol Information". You should see the SSH Host Key Fingerprint in the "Protocol" tab.

For FileZilla:

  1. Download and install Filezilla.
  2. Connect to your sFTP using your hostname, username, and password
  3. Once you're connected, you'll be prompted to accept the SSH Host Key. At this point, I would get a screen shot of the SSH Host Key or write it down. Once you get past the SSH Key pop-up and haven't copied this key, it's going to be a challenge to get that key out of FileZilla. This is because FileZilla uses a adapted PuTTY component for sFTP support. FileZilla and PuTTY share the host key cache.
  4. Here's a way to get the host key out of FileZilla (it's long and involves the registry).

If you get 'click happy', you're likely to miss the dialog and will probably need to re-install FileZilla (with some registry magic) to review the key again. So, read the prompts that you're being asked to click through Smile | :) .

That was longer than intended...now charge forward...

Using the Code

Now the best part! Go here to grab the WinSCP assembly. We're assuming that you are well versed in Visual Studio project files and how to add, remove, compile, and build projects.

There will be two files in the .NET assembly WinSCP download. One will be the actual assembly itself (WinSCPnet.dll) and the second file will be the executable, WinSCP.exe.

Add both of these files to your Visual Studio project output folder; which should be the /obj/debug folder. For simplicity sake, the files WinSCPnet.dll and WinSCp.exe should be copied into the output folder for this scenario. If you want to use a different folder, then you can set the "Session.ExecutablePath" property of the WinSCP API to tell the assembly to look in a different folder other than the output path. A more detailed instruction list is available here at the WinSCP site.

In our scenario, we were going to be doing two functions:

  1. Get the files off of a sFTP site, or
  2. Put the files on an sFTP site.

The code is going be really similar for both of these actions.

Get Files (pull down from sFTP - Download)

using WinSCP; //Namespace 
...
//Get Files - ideally you would want to wrap this into a try...catch 
//and possible execute more than once if you can't connect the first time. 
SessionOptions sessionOptions = new SessionOptions
{
    Protocol = Protocol.Sftp,
    HostName = ftpServerName, //hostname e.g. IP: 192.54.23.32, or mysftpsite.com
    UserName = ftpUser,
    Password = ftpPwd, 
    PortNumber = 22,
    SshHostKeyFingerprint = "ssh - rsa //followed by your 16 bit key" 
};
using (Session session = new Session())
{
    session.SessionLogPath = "your log path";
    Session.Open(sessionOptions); //Attempts to connect to your sFtp site
    //Get Ftp File
    TransferOptions transferOptions = new TransferOptions(); 
    transferOptions.TransferMode = TransferMode.Binary; //The Transfer Mode - Automatic, Binary, or Ascii 
    transferOptions.FilePermissions = null;  //Permissions applied to remote files; 
    //<em style="font-size: 9pt;">null for default permissions.  
    //Can set <em style="font-size: 9pt;">user, Group, or other Read/Write/Execute permissions.  
    transferOptions.PreserveTimestamp = false;  //Set last write time of destination file 
    //to that of source file - basically change the timestamp to match destination and source files.    
    transferOptions.ResmeSupport.State = TransferResumeSupportState.Off;
     
     TransferOperationalResult transferResult;
    //the parameter list is: remote Path, Local Path with filename 
    //(optional - if different from remote path), Delete source file?, transfer Options  
    transferResult = session.GetFiles("/" + filenameToGet, PathToPlaceFile, false, transferOptions; 
    //Throw on any error 
    transferResult.Check()  
    //Log information and break out if necessary  
} 

Put Files (Send FTP Files - Upload)

using WinSCP; //Namespace 
...
//Send Ftp Files - same idea as above - try...catch and try to repeat this code 
//if you can't connect the first time, timeout after a certain number of tries. 
SessionOptions sessionOptions = new SessionOptions
{
    Protocol = Protocol.Sftp,
    HostName = ftpServerName, //hostname e.g. IP: 192.54.23.32, or mysftpsite.com
    UserName = ftpUser,
    Password = ftpPwd, 
    PortNumber = 22,
    SshHostKeyFingerprint = "ssh - rsa //followed by your 16 bit key" 
};
using (Session session = new Session())
{
    session.SessionLogPath = "your log path";
    Session.Open(sessionOptions); //Attempts to connect to your sFtp site
    //Get Ftp File
    TransferOptions transferOptions = new TransferOptions(); 
    transferOptions.TransferMode = TransferMode.Binary; //The Transfer Mode - 
    //<em style="font-size: 9pt;">Automatic, Binary, or Ascii  
    transferOptions.FilePermissions = null; //Permissions applied to remote files; 
    //null for default permissions.  Can set user, 
    //Group, or other Read/Write/Execute permissions. 
    transferOptions.PreserveTimestamp = false; //Set last write time of 
    //destination file to that of source file - basically change the timestamp 
    //to match destination and source files.   
    transferOptions.ResmeSupport.State = TransferResumeSupportState.Off;
     
     TransferOperationalResult transferResult;
    //the parameter list is: local Path, Remote Path, Delete source file?, transfer Options  
    transferResult = session.PutFiles(localPathWithFilename, RemotePath, false, transferOptions; 
    //Throw on any error 
    transferResult.Check() 
    //Log information and break out if necessary  
} 

The WinSCP site has GREAT documentation on all the methods covered above and examples (C# and VB.NET) can be found here. The attempt here is to make it all concise and just get the sFTP transfer working quickly.

Points of Interest

Do keep in mind that sFTP is not the same as FTPS. sFTP is 'secure shell' and FTPs is SSL over FTP - totally two different concepts. A simple search will get you tons of information.

The WinSCP .NET wrapper has been nothing short of a life saver. There are other solutions out there (Granados, SharpSSH, etc.) and find one that works for you. Here is a discussion on sFTP libraries that you could use from stackoverflow.com.

Hope that this helps and corrections are welcome!

History

  • 6th May, 2014: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

JagB
Unknown
No Biography provided

You may also be interested in...

Comments and Discussions

 
QuestionI do not understand C#. How should this code look in VB.NET? Pin
Member 1182110811-Apr-16 18:42
memberMember 1182110811-Apr-16 18:42 
QuestionGetting Exception whiling uploading files to SFTP Pin
Member 785047919-Mar-15 3:08
memberMember 785047919-Mar-15 3:08 
GeneralIt was great for me Pin
PowerGirl2020-Feb-15 23:41
memberPowerGirl2020-Feb-15 23:41 
QuestionGetting Exception Pin
Adnan Aman16-Jan-15 6:59
memberAdnan Aman16-Jan-15 6:59 
QuestionThanks for this! Pin
bimplebean29-Dec-14 6:28
memberbimplebean29-Dec-14 6:28 
GeneralMessage Automatically Removed Pin
6-May-14 21:36
memberTú Camry6-May-14 21:36 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.160525.2 | Last Updated 6 May 2014
Article Copyright 2014 by JagB
Everything else Copyright © CodeProject, 1999-2016
Layout: fixed | fluid