How to access a SFTP server using SSH.NET in C#
By FoxLearn 2/15/2025 3:03:49 AM 369
SFTP (SSH File Transfer Protocol), also known as Secure File Transfer Protocol, is an extension of SSH that provides secure file transfer capabilities. While many graphical tools integrate SFTP for end-users, as a developer, you can integrate SFTP features into your application. This allows users to perform all tasks within a single interface, streamlining their experience.
In this guide, we’ll cover how to install and perform common SFTP tasks in a WinForms C# application using the popular SSH.NET library.
1. Installing SSH.NET
SSH.NET is a comprehensive SSH library for .NET optimized for parallelism. This project was inspired by Sharp.SSH and was rewritten to support .NET 4.0 without third-party dependencies. It provides both synchronous and asynchronous SFTP functionality.
First, install the SSH.NET library via NuGet. This library provides SSH and SFTP functionality in .NET applications.
- Open your project in Visual Studio.
- Right-click on the project solution in Solution Explorer and select Manage NuGet Packages.
- Navigate to the Browse tab, search for
SSH.NET
by author Renci, and install it.
Once SSH.NET is installed, you can use it to connect to an SFTP server.
Below is a simple example of how to connect to an SFTP server, list files, and download a file using synchronous operations.
2. Using SSH.NET for Common SFTP Tasks
Listing Files from a Directory (Sync & Async)
To list the contents of a directory:
private void listFiles() { string host = @"yourSftpServer.com"; string username = "root"; string password = @"p4ssw0rd"; string remoteDirectory = "/some/example/directory"; using (SftpClient sftp = new SftpClient(host, username, password)) { try { sftp.Connect(); var files = sftp.ListDirectory(remoteDirectory); foreach (var file in files) { Console.WriteLine(file.Name); } sftp.Disconnect(); } catch (Exception e) { Console.WriteLine("Error: " + e.Message); } } }
For example, using a separate thread
Thread myThread = new System.Threading.Thread(delegate () { string remoteDirectory = "/some/example/directory"; string host = @"yourSftpServer.com"; string username = "root"; string password = @"p4ssw0rd"; using (SftpClient sftp = new SftpClient(host, username, password)) { try { sftp.Connect(); var files = sftp.ListDirectory(remoteDirectory); foreach (var file in files) { Console.WriteLine(file.Name); } sftp.Disconnect(); } catch (Exception er) { Console.WriteLine("Error: " + er.Message); } } }); myThread.Start();
Connecting with a Private Key and Password
If you need to authenticate using an SSH private key instead of a password, you can do so by providing the private key in the connection setup.
string host = @"yourSftpServer.com"; string username = "root"; string password = @"p4ssw0rd"; string privateKeyPath = @"path\to\privateKey.pem"; // Path to your private key file PrivateKeyFile keyFile = new PrivateKeyFile(privateKeyPath); var keyFiles = new[] { keyFile }; var methods = new List<AuthenticationMethod> { new PasswordAuthenticationMethod(username, password), new PrivateKeyAuthenticationMethod(username, keyFiles) }; ConnectionInfo connectionInfo = new ConnectionInfo(host, 22, username, methods.ToArray()); using (var client = new SftpClient(connectionInfo)) { client.Connect(); // Perform operations with the client client.Disconnect(); }
Downloading a Single File (Sync & Async)
To download a file:
public void downloadFile() { string host = @"yourSftpServer.com"; string username = "root"; string password = @"p4ssw0rd"; string pathRemoteFile = "/var/www/vhosts/some-folder/file_server.txt"; string pathLocalFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "download_sftp_file.txt"); using (SftpClient sftp = new SftpClient(host, username, password)) { try { sftp.Connect(); Console.WriteLine("Downloading {0}", pathRemoteFile); using (Stream fileStream = File.OpenWrite(pathLocalFile)) { sftp.DownloadFile(pathRemoteFile, fileStream); } sftp.Disconnect(); } catch (Exception er) { Console.WriteLine("Error: " + er.Message); } } }
For example, using a separate thread
Thread myThread = new System.Threading.Thread(delegate () { string host = @"yourSftpServer.com"; string username = "root"; string password = @"p4ssw0rd"; string pathRemoteFile = "/var/www/vhosts/some-folder/file_server.txt"; string pathLocalFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "download_sftp_file.txt"); using (SftpClient sftp = new SftpClient(host, username, password)) { try { sftp.Connect(); Console.WriteLine("Downloading {0}", pathRemoteFile); using (Stream fileStream = File.OpenWrite(pathLocalFile)) { sftp.DownloadFile(pathRemoteFile, fileStream); } sftp.Disconnect(); } catch (Exception er) { Console.WriteLine("Error: " + er.Message); } } }); myThread.Start();
Downloading an Entire Directory
To download an entire directory and its contents (including subfolders):
private void DownloadDirectory(SftpClient client, string source, string destination, bool recursive = false) { var files = client.ListDirectory(source); foreach (SftpFile file in files) { if (!file.IsDirectory && !file.IsSymbolicLink) { DownloadFile(client, file, destination); } else if (file.IsSymbolicLink) { Console.WriteLine("Symbolic link ignored: {0}", file.FullName); } else if (file.Name != "." && file.Name != "..") { var dir = Directory.CreateDirectory(Path.Combine(destination, file.Name)); if (recursive) { DownloadDirectory(client, file.FullName, dir.FullName); } } } } private void DownloadFile(SftpClient client, SftpFile file, string directory) { Console.WriteLine("Downloading {0}", file.FullName); using (Stream fileStream = File.OpenWrite(Path.Combine(directory, file.Name))) { client.DownloadFile(file.FullName, fileStream); } }
To execute the directory download asynchronously:
Thread myThread = new System.Threading.Thread(delegate () { string host = @"yourSftpServer.com"; string username = "root"; string password = @"p4ssw0rd"; string pathRemoteDirectory = "/var/www/vhosts/some-folder-to-download"; string pathLocalDirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "example-local-folder"); using (SftpClient sftp = new SftpClient(host, username, password)) { try { sftp.Connect(); bool recursiveDownload = true; DownloadDirectory(sftp, pathRemoteDirectory, pathLocalDirectory, recursiveDownload); sftp.Disconnect(); } catch (Exception er) { Console.WriteLine("Error: " + er.Message); } } }); myThread.Start();
Deleting a Remote File
To delete a file from the remote server:
private void deleteFile() { string host = @"yourSftpServer.com"; string username = "root"; string password = @"p4ssw0rd"; string pathRemoteFileToDelete = "/var/www/vhosts/folder/somefile.txt"; using (SftpClient sftp = new SftpClient(host, username, password)) { try { sftp.Connect(); sftp.DeleteFile(pathRemoteFileToDelete); sftp.Disconnect(); } catch (Exception er) { Console.WriteLine("Error: " + er.Message); } } }
Using SSH.NET in C#, you can easily connect to an SFTP server, list files, upload/download files, and perform other SFTP tasks. This example demonstrates a simple connection and file download, but SSH.NET also supports more advanced features such as authentication with private keys, uploading files, and handling directories.
- Primitive types in C#
- How to set permissions for a directory in C#
- How to Convert Int to Byte Array in C#
- How to Convert string list to int list in C#
- How to convert timestamp to date in C#
- How to Get all files in a folder in C#
- How to use Channel as an async queue in C#
- Case sensitivity in JSON deserialization