如何在WinForms中使用带有C#的SSH.NET(同步和异步)访问SFTP服务器

本文概述

  • 1.安装SSH.NET
  • 2.用法
SFTP代表SSH文件传输协议或安全文件传输协议, 是与SSH打包在一起的独立协议, 在完全安全的连接上以类似的方式工作。尽管SFTP已集成到用户可以使用的许多图形工具中, 但是如果你是开发人员, 则可以将此类功能集成到你的应用程序中。这样, 你可以处理用户使用此工具时的实际操作, 并且他们将继续使用单个应用程序来处理所有事情, 即你的应用程序。
在本文中, 我们将向你展示在WinForms C#中使用广为人知的SSH.NET库使用SFTP时, 如何安装以及如何完成一些基本任务。
1.安装SSH.NET 第一步, 通过NuGET继续在项目中安装SSH.NET库。 SSH.NET是针对.NET的安全Shell(SSH)库, 已针对并行性进行了优化。这个项目的灵感来自从Java移植的Sharp.SSH库, 而且似乎已经有一段时间没有被支持了。该库是使用.NET 4.0进行的完全重写, 没有任何第三方依赖性, 并使用并行性来实现最佳性能。它为同步和异步操作提供SFTP功能, 这正是我们所需要的。
在Visual Studio中打开你的项目, 然后转到窗口右上角的解决方案资源管理器, 然后右键单击项目的解决方案。从上下文菜单中选择” 管理NuGet软件包” 选项:
如何在WinForms中使用带有C#的SSH.NET(同步和异步)访问SFTP服务器

文章图片
从紧急窗口(或选项卡)导航至” 浏览” 选项卡并搜索SSH.NET。从结果列表中, 选择authro Renci的第一个选项, 然后继续安装:
如何在WinForms中使用带有C#的SSH.NET(同步和异步)访问SFTP服务器

文章图片
库安装完成后, 你将可以在项目中使用它而不会出现问题。不要忘了在你的类的顶部(你要使用它的地方)和其他添加SshNet类型:
using Renci.SshNet; using Renci.SshNet.Sftp; using System.IO;

2.用法 用法将基本上通过许多示例来显示, 这些示例说明了如何使用SFTP实现所需的最关键的任务:
列出目录中的文件
你可以使用以下使用SFTPClient.ListDirectory方法的代码段(同步)列出目录的内容:
/// < summary> /// List a remote directory in the console./// < /summary> 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("An exception has been caught " + e.ToString()); }}}

或通过在另一个线程中运行代码来异步:
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("An exception has been caught " + er.ToString()); }}}); myThread.Start();

连接密钥文件和密码
如果你同时使用私钥文件和密码来连接到SFTP服务器, 则可以使用以下代码段创建连接:
string host = @"yourSftpServer.com"; string username = "root"; string password = @"p4ssw0rd"; PrivateKeyFile keyFile = new PrivateKeyFile(@"path/to/OpenSsh-RSA-key.ppk"); var keyFiles = new[] { keyFile }; var methods = new List< AuthenticationMethod> (); methods.Add(new PasswordAuthenticationMethod(username, password)); methods.Add(new PrivateKeyAuthenticationMethod(username, keyFiles)); ConnectionInfo con = new ConnectionInfo(host, 22, username, methods.ToArray()); using (var client = new SftpClient(con)){client.Connect(); // Do what you need with the client !client.Disconnect(); }

下载单个文件
要下载文件, 可以使用SFTPClient.DownloadFile方法, 并使用System.IO.File.OpenWrite方法在本地写入:
/// < summary> /// Downloads a file in the desktop synchronously/// < /summary> public void downloadFile(){string host = @"yourSftpServer.com"; string username = "root"; string password = @"p4ssw0rd"; // Path to file on SFTP serverstring pathRemoteFile = "/var/www/vhosts/some-folder/file_server.txt"; // Path where the file should be saved once downloaded (locally)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("An exception has been caught " + er.ToString()); }}}

或者, 你可以使其异步创建另一个线程并在其中执行代码:
Thread myThread = new System.Threading.Thread(delegate () {string host = @"yourSftpServer.com"; string username = "root"; string password = @"p4ssw0rd"; // Path to file on SFTP serverstring pathRemoteFile = "/var/www/vhosts/some-folder/file_server.txt"; // Path where the file should be saved once downloaded (locally)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("An exception has been caught " + er.ToString()); }}}); myThread.Start();

下载整个目录
如果你需要下载整个目录(甚至是子文件夹和子文件), 则需要创建2个函数, 其中之一是递归的。第一个功能是DownloadFile, 它允许你通过远程目录和本地路径作为参数下载文件。第二个功能是DownloadDirectory方法, 该方法将列出Providen目录中的所有文件并对其进行迭代。分别地, 如果该项是文件, 那么它将使用DownloadFile方法下载它, 或者如果它是一个文件夹, 则它将创建它:
/// < summary> /// Downloads a remote directory into a local directory/// < /summary> /// < param name="client"> < /param> /// < param name="source"> < /param> /// < param name="destination"> < /param> private void DownloadDirectory(SftpClient client, string source, string destination, bool recursive = false){// List the files and folders of the directoryvar files = client.ListDirectory(source); // Iterate over themforeach (SftpFile file in files){// If is a file, download itif (!file.IsDirectory & & !file.IsSymbolicLink){DownloadFile(client, file, destination); }// If it's a symbolic link, ignore itelse if (file.IsSymbolicLink){Console.WriteLine("Symbolic link ignored: {0}", file.FullName); }// If its a directory, create it locally (and ignore the .. and .=) //. is the current folder//.. is the folder above the current folder -the folder that contains the current folder.else if (file.Name != "." & & file.Name != ".."){var dir = Directory.CreateDirectory(Path.Combine(destination, file.Name)); // and start downloading it's content recursively :) in case it's requiredif (recursive){DownloadDirectory(client, file.FullName, dir.FullName); }}}}/// < summary> /// Downloads a remote file through the client into a local directory/// < /summary> /// < param name="client"> < /param> /// < param name="file"> < /param> /// < param name="directory"> < /param> 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); }}

接下来, 你可以继续使用凭??据创建客户端, 并使用先前创建的方法开始下载远程目录。请注意, 由于下载整个目录会花费一些时间, 因此建议仅以异步方式(创建线程)使用它, 但这只是一个建议, 你可以解开代码:
Thread myThread = new System.Threading.Thread(delegate () {string host = @"yourSftpServer.com"; string username = "root"; string password = @"p4ssw0rd"; // Path to folder on SFTP serverstring pathRemoteDirectory = "/var/www/vhosts/some-folder-to-download"; // Path where the file should be saved once downloaded (locally)string pathLocalDirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "example-local-folder"); using (SftpClient sftp = new SftpClient(host, username, password)){try{sftp.Connect(); // By default, the method doesn't download subdirectories// therefore you need to indicate that you want their content toobool recursiveDownload = true; // Start download of the directoryDownloadDirectory(sftp, pathRemoteDirectory, pathLocalDirectory, recursiveDownload); sftp.Disconnect(); }catch (Exception er){Console.WriteLine("An exception has been caught " + er.ToString()); }}}); myThread.Start();

删除远端档案
要从远程目录中删除文件, 请使用SFTPClient.DeleteFile方法:
/// < summary> /// Delete a remote file/// < /summary> private void deleteFile(){string host = @"yourSftpServer.com"; string username = "root"; string password = @"p4ssw0rd"; // Path to folder on SFTP serverstring pathRemoteFileToDelete = "/var/www/vhosts/folder/somefile.txt"; using (SftpClient sftp = new SftpClient(host, username, password)){try{sftp.Connect(); // Delete filesftp.DeleteFile(pathRemoteFileToDelete); sftp.Disconnect(); }catch (Exception er){Console.WriteLine("An exception has been caught " + er.ToString()); }}}

【如何在WinForms中使用带有C#的SSH.NET(同步和异步)访问SFTP服务器】编码愉快!

    推荐阅读