You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
536 lines
20 KiB
536 lines
20 KiB
using System.Net;
|
|
using System.Text;
|
|
using FluentFTP;
|
|
using File = System.IO.File;
|
|
using Renci.SshNet;
|
|
using Renci.SshNet.Sftp;
|
|
|
|
namespace Tiobon.PublishHelper
|
|
{
|
|
/// <summary>
|
|
/// SFTP操作类
|
|
/// </summary>
|
|
public class SftpHelper
|
|
{
|
|
#region 下载文件
|
|
/// <summary>
|
|
/// 下载单个文件
|
|
/// </summary>
|
|
/// <param name="server"></param>
|
|
/// <param name="remotePath"></param>
|
|
/// <param name="localFile"></param>
|
|
/// <param name="b_log"></param>
|
|
/// <returns></returns>
|
|
public static bool DownloadFile(Server server, string remoteFile, string localFile, bool b_log = false, Action<long, ulong> progress = null, Action completedAction = null)
|
|
{
|
|
bool b_suc = false;
|
|
try
|
|
{
|
|
if (!Utility.Ping(server.Ip, b_log))
|
|
return b_suc;
|
|
|
|
using (var ftp = new FtpClient(server.Ip, server.UserName, server.SuPassword, server.Port))
|
|
{
|
|
ftp.Connect();
|
|
if (b_log)
|
|
Utility.SendLog("下载", $"下载文件 {remoteFile}");
|
|
if (File.Exists(localFile))
|
|
{
|
|
File.Delete(localFile);
|
|
Thread.Sleep(50);
|
|
}
|
|
var size = ftp.GetFileSize(remoteFile);
|
|
// define the progress tracking callback
|
|
Action<FtpProgress> progress1 = delegate (FtpProgress p)
|
|
{
|
|
if (p.Progress == 1)
|
|
{
|
|
if (b_log)
|
|
Utility.SendLog("下载", $"成功 {remoteFile} =>> {localFile} len {size} byte");
|
|
b_suc = true;
|
|
}
|
|
else
|
|
//progress?.Invoke(sftFile.Length, pro);
|
|
{
|
|
// percent done = (p.Progress * 100)
|
|
progress?.Invoke(size, (ulong)p.Progress);
|
|
}
|
|
};
|
|
|
|
// download a file with progress tracking
|
|
ftp.DownloadFile(localFile, remoteFile, FtpLocalExists.Overwrite, FtpVerify.None, progress1);
|
|
|
|
}
|
|
|
|
//using (SftpClient sftp = new SftpClient(server.Ip, server.Port, "root", server.SuPassword))
|
|
//{
|
|
// sftp.Connect();
|
|
// if (sftp.Exists(remoteFile))
|
|
// {
|
|
// if (b_log)
|
|
// Utility.SendLog("下载", $"下载文件 {remoteFile}");
|
|
// if (File.Exists(localFile))
|
|
// {
|
|
// File.Delete(localFile);
|
|
// System.Threading.Thread.Sleep(50);
|
|
// }
|
|
// var sftFile = sftp.ListDirectory(remoteFile.Substring(0, remoteFile.LastIndexOf('/'))).Where(o => o.FullName == remoteFile).FirstOrDefault();
|
|
// using (var file = File.OpenWrite(localFile))
|
|
// {
|
|
// sftp.DownloadFile(remoteFile, file, pro =>
|
|
// {
|
|
// progress?.Invoke(sftFile.Length, pro);
|
|
// });
|
|
// if (b_log)
|
|
// Utility.SendLog("下载", $"成功 {remoteFile} =>> {localFile} len {file.Length} byte");
|
|
// b_suc = true;
|
|
// }
|
|
// }
|
|
// else
|
|
// {
|
|
// if (b_log)
|
|
// Utility.SendLog("下载", $"文件不存在 {remoteFile}");
|
|
// }
|
|
//}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
if (b_log)
|
|
Utility.SendLog("下载", $"下载文件失败:{remoteFile} {ex.Message}");
|
|
}
|
|
finally
|
|
{
|
|
completedAction?.Invoke();
|
|
}
|
|
return b_suc;
|
|
}
|
|
#endregion
|
|
|
|
#region 上传文件
|
|
/// <summary>
|
|
/// 上传单个文件
|
|
/// </summary>
|
|
/// <param name="server"></param>
|
|
/// <param name="localFile"></param>
|
|
/// <param name="remoteFile"></param>
|
|
/// <param name="progress"></param>
|
|
public static void UploadFile(Server server, string localFile, string remoteFile, Action<long, ulong> progress = null, bool create = false)
|
|
{
|
|
if (!Utility.Ping(server.Ip))
|
|
return;
|
|
|
|
try
|
|
{
|
|
FtpClient client = new FtpClient();
|
|
client.Host = server.Ip;
|
|
client.Port = server.Port;
|
|
client.Credentials = new NetworkCredential(server.UserName, server.SuPassword);
|
|
client.AutoConnect();
|
|
|
|
using (var file = File.OpenRead(localFile))
|
|
{
|
|
try
|
|
{
|
|
var len = file.Length;
|
|
client.UploadFile(localFile, remoteFile);
|
|
Utility.SendLog("上传", $"成功 {localFile} =>> {remoteFile} len {len} byte");
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Utility.SendLog("上传", $"失败 {remoteFile} 原因:{e}");
|
|
}
|
|
}
|
|
client.Disconnect();
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
Utility.SendLog("上传", $"失败 {remoteFile} 原因:{E}");
|
|
}
|
|
|
|
#region 作废代码
|
|
//using (SftpClient sftp = new SftpClient(server.Ip, server.Port, server.UserName, server.SuPassword))
|
|
//{
|
|
// sftp.Connect();
|
|
// using (var file = File.OpenRead(localFile))
|
|
// {
|
|
// try
|
|
// {
|
|
// if (!sftp.Exists(remoteFile) && create)
|
|
// {
|
|
// sftp.Create(remoteFile);
|
|
// }
|
|
// var len = file.Length;
|
|
// sftp.UploadFile(file, remoteFile, pro =>
|
|
// {
|
|
// progress?.Invoke(len, pro);
|
|
// });
|
|
// Utility.SendLog("上传", $"成功 {localFile} =>> {remoteFile} len {len} byte");
|
|
// }
|
|
// catch (Exception e)
|
|
// {
|
|
// Utility.SendLog("上传", $"失败 {remoteFile} 原因:{e}");
|
|
// }
|
|
// }
|
|
//}
|
|
#endregion
|
|
}
|
|
/// <summary>
|
|
/// 批量上传文件
|
|
/// </summary>
|
|
/// <param name="server"></param>
|
|
/// <param name="localPath"></param>
|
|
/// <param name="remotePath"></param>
|
|
/// <param name="files"></param>
|
|
/// <param name="progress"></param>
|
|
public static void UploadFile(Server server, string localPath, string remotePath, List<string> files, Action<int, int> progress)
|
|
{
|
|
if (!Utility.Ping(server.Ip))
|
|
return;
|
|
|
|
try
|
|
{
|
|
progress(files.Count, 0);
|
|
|
|
FtpClient sftp = new FtpClient();
|
|
sftp.Host = server.Ip;
|
|
sftp.Port = server.Port;
|
|
sftp.Credentials = new NetworkCredential(server.UserName, server.SuPassword);
|
|
sftp.AutoConnect();
|
|
|
|
var count = files.Count;
|
|
var index = 0;
|
|
files?.ForEach(fname =>
|
|
{
|
|
if (Utility.m_StopPublish)
|
|
return;
|
|
var localFileName = $"{localPath}\\{fname}";
|
|
var remoteFileName = $"{remotePath}/{fname.Replace("\\", "/")}";
|
|
using (var file = File.OpenRead(localFileName))
|
|
{
|
|
var len = file.Length;
|
|
try
|
|
{
|
|
index++;
|
|
if (fname.Contains("\\"))
|
|
{
|
|
StringBuilder sb = new StringBuilder();
|
|
var ff = fname.Substring(0, fname.LastIndexOf("\\")).Split(new string[] { "\\" }, StringSplitOptions.RemoveEmptyEntries);
|
|
ff.ToList().ForEach(f =>
|
|
{
|
|
sb.Append($"/{f}");
|
|
var fpath = $"{remotePath}{sb}";
|
|
if (!sftp.DirectoryExists(fpath))
|
|
{
|
|
sftp.CreateDirectory(fpath);
|
|
Utility.SendLog("上传", $"创建目录成功 {fpath}");
|
|
}
|
|
});
|
|
}
|
|
//sftp.UploadFile(file, remoteFileName);
|
|
sftp.UploadFile(localFileName, remoteFileName);
|
|
progress(count, index);
|
|
Utility.SendLog("上传", $"[{index}/{count}]成功 {localPath}\\{fname} =>> {remoteFileName} len {len} byte");
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Utility.SendLog("上传", $"[{index}/{count}] 失败 原因:{fname} {e}");
|
|
try
|
|
{
|
|
Utility.SendLog("重新上传", $"[{index}/{count}] {fname} ");
|
|
sftp.UploadFile(localFileName, remoteFileName);
|
|
progress(count, index);
|
|
Utility.SendLog("上传", $"[{index}/{count}]成功 {localPath}\\{fname} =>> {remoteFileName} len {len} byte");
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
Utility.SendLog("上传", $"[{index}/{count}] 失败 原因:{fname} {E}");
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
});
|
|
sftp.Disconnect();
|
|
|
|
#region 作废代码
|
|
//using (SftpClient sftp = new SftpClient(server.Ip, server.Port, "root", server.SuPassword))
|
|
//{
|
|
// sftp.Connect();
|
|
// var count = files.Count;
|
|
// var index = 0;
|
|
// files?.ForEach(fname =>
|
|
// {
|
|
// if (Utility.m_StopPublish)
|
|
// return;
|
|
// var localFileName = $"{localPath}\\{fname}";
|
|
// var remoteFileName = $"{remotePath}/{fname.Replace("\\", "/")}";
|
|
// using (var file = File.OpenRead(localFileName))
|
|
// {
|
|
// try
|
|
// {
|
|
// index++;
|
|
// var len = file.Length;
|
|
// if (fname.Contains("\\"))
|
|
// {
|
|
// StringBuilder sb = new StringBuilder();
|
|
// var ff = fname.Substring(0, fname.LastIndexOf("\\")).Split(new string[] { "\\" }, StringSplitOptions.RemoveEmptyEntries);
|
|
// ff.ToList().ForEach(f =>
|
|
// {
|
|
// sb.Append($"/{f}");
|
|
// var fpath = $"{remotePath}{sb}";
|
|
// if (!sftp.Exists(fpath))
|
|
// {
|
|
// sftp.CreateDirectory(fpath);
|
|
// Utility.SendLog("上传", $"创建目录成功 {fpath}");
|
|
// }
|
|
// });
|
|
// }
|
|
// sftp.UploadFile(file, remoteFileName);
|
|
// progress(count, index);
|
|
// Utility.SendLog("上传", $"[{index}/{count}]成功 {localPath}\\{fname} =>> {remoteFileName} len {len} byte");
|
|
// }
|
|
// catch (Exception e)
|
|
// {
|
|
// Utility.SendLog("上传", $"[{index}/{count}] 失败 原因:{fname} {e}");
|
|
// }
|
|
// }
|
|
|
|
// });
|
|
//}
|
|
#endregion
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Utility.SendLog("", ex.ToString());
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region 获取文件
|
|
/// <summary>
|
|
/// 获取当前目录的文件列表
|
|
/// </summary>
|
|
/// <param name="server"></param>
|
|
/// <param name="remotePath"></param>
|
|
/// <returns></returns>
|
|
public static List<SftpFile> ListFiles(Server server, string remotePath)
|
|
{
|
|
List<SftpFile> list = new List<SftpFile>();
|
|
//try
|
|
//{
|
|
// using (SftpClient sftp = new SftpClient(server.Ip, server.Port, "root", server.SuPassword))
|
|
// {
|
|
// sftp.Connect();
|
|
// list = sftp.ListDirectory(remotePath).Where(f => f.IsRegularFile).ToList();
|
|
// }
|
|
//}
|
|
//catch (Exception ex)
|
|
//{
|
|
// Utility.SendLog("", $"获取文件夹失败:{remotePath} {ex.Message}");
|
|
//}
|
|
return list;
|
|
}
|
|
|
|
public static List<FtpListItem> GetListing(Server server, string remotePath)
|
|
{
|
|
FtpClient sftp = new FtpClient();
|
|
sftp.Host = server.Ip;
|
|
sftp.Port = server.Port;
|
|
sftp.Credentials = new NetworkCredential(server.UserName, server.SuPassword);
|
|
sftp.AutoConnect();
|
|
|
|
List<FtpListItem> list = new List<FtpListItem>();
|
|
try
|
|
{
|
|
foreach (FtpListItem item in sftp.GetListing(remotePath))
|
|
{
|
|
list.Add(item);
|
|
// if this is a file
|
|
//if (item.Type == FtpFileSystemObjectType.File)
|
|
//{
|
|
|
|
// // get the file size
|
|
// long size = sftp.GetFileSize(item.FullName);
|
|
|
|
// // calculate a hash for the file on the server side (default algorithm)
|
|
// FtpHash hash = sftp.GetChecksum(item.FullName);
|
|
//}
|
|
|
|
//// get modified date/time of the file or folder
|
|
//DateTime time = sftp.GetModifiedTime(item.FullName);
|
|
}
|
|
sftp.Disconnect();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Utility.SendLog("", $"获取文件夹失败:{remotePath} {ex.Message}");
|
|
}
|
|
return list;
|
|
}
|
|
#endregion
|
|
|
|
#region 获取文件夹
|
|
/// <summary>
|
|
/// 获取当前目录的文件夹列表
|
|
/// </summary>
|
|
/// <param name="server"></param>
|
|
/// <param name="remotePath"></param>
|
|
/// <returns></returns>
|
|
public static List<SftpFile> ListDirectory(Server server, string remotePath)
|
|
{
|
|
List<SftpFile> list = new List<SftpFile>();
|
|
try
|
|
{
|
|
FtpClient sftp = new FtpClient();
|
|
sftp.Host = server.Ip;
|
|
sftp.Port = server.Port;
|
|
sftp.Credentials = new NetworkCredential(server.UserName, server.SuPassword);
|
|
sftp.AutoConnect();
|
|
sftp.GetListing();
|
|
|
|
//using (SftpClient sftp = new SftpClient(server.Ip, server.Port, "root", server.SuPassword))
|
|
//{
|
|
// sftp.Connect();
|
|
// list = sftp.ListDirectory(remotePath).Where(f => f.IsDirectory && f.Name != "." && f.Name != "..").ToList();
|
|
//}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Utility.SendLog("", $"获取文件夹失败:{remotePath} {ex.Message}");
|
|
}
|
|
return list;
|
|
}
|
|
#endregion
|
|
|
|
#region 文件/文件夹是否存在
|
|
/// <summary>
|
|
/// 文件/文件夹是否存在
|
|
/// </summary>
|
|
/// <param name="server"></param>
|
|
/// <param name="path"></param>
|
|
/// <param name="create"></param>
|
|
/// <returns></returns>
|
|
public static bool Exists(Server server, string path)
|
|
{
|
|
bool b_suc = false;
|
|
if (!Utility.Ping(server.Ip))
|
|
{
|
|
return b_suc;
|
|
}
|
|
try
|
|
{
|
|
//using (SftpClient sftp = new SftpClient(server.Ip, server.Port, "root", server.SuPassword))
|
|
//{
|
|
// sftp.Connect();
|
|
// b_suc = sftp.Exists(path);
|
|
//}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Utility.SendLog("", ex.ToString());
|
|
}
|
|
return b_suc;
|
|
}
|
|
|
|
public static void CreateDirectory(Server server, string path)
|
|
{
|
|
if (!Utility.Ping(server.Ip))
|
|
{
|
|
return;
|
|
}
|
|
try
|
|
{
|
|
using (SftpClient sftp = new SftpClient(server.Ip, server.Port, "root", server.SuPassword))
|
|
{
|
|
sftp.Connect();
|
|
if (!sftp.Exists(path))
|
|
{
|
|
sftp.CreateDirectory(path);
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Utility.SendLog("", ex.ToString());
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region 删除文件
|
|
/// <summary>
|
|
/// 删除文件
|
|
/// </summary>
|
|
/// <param name="server"></param>
|
|
/// <param name="path"></param>
|
|
/// <returns></returns>
|
|
public static bool Delete(Server server, string path)
|
|
{
|
|
bool b_suc = false;
|
|
if (!Utility.Ping(server.Ip))
|
|
return b_suc;
|
|
|
|
try
|
|
{
|
|
FtpClient sftp = new FtpClient();
|
|
sftp.Host = server.Ip;
|
|
sftp.Port = server.Port;
|
|
sftp.Credentials = new NetworkCredential(server.UserName, server.SuPassword);
|
|
sftp.AutoConnect();
|
|
|
|
//using (SftpClient sftp = new SftpClient(server.Ip, server.Port, "root", server.SuPassword))
|
|
//{
|
|
// sftp.Connect();
|
|
// if (sftp.FileExists(path))
|
|
// sftp.Delete(path);
|
|
// b_suc = true;
|
|
//}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Utility.SendLog("", ex.ToString());
|
|
}
|
|
return b_suc;
|
|
}
|
|
#endregion
|
|
|
|
#region 删除文件夹
|
|
/// <summary>
|
|
/// 删除文件夹
|
|
/// </summary>
|
|
/// <param name="server"></param>
|
|
/// <param name="path"></param>
|
|
/// <returns></returns>
|
|
public static bool DeleteDirectory(Server server, string path)
|
|
{
|
|
bool b_suc = false;
|
|
if (!Utility.Ping(server.Ip))
|
|
return b_suc;
|
|
|
|
try
|
|
{
|
|
FtpClient sftp = new FtpClient();
|
|
sftp.Host = server.Ip;
|
|
sftp.Port = server.Port;
|
|
sftp.Credentials = new NetworkCredential(server.UserName, server.SuPassword);
|
|
sftp.AutoConnect();
|
|
if (sftp.DirectoryExists(path))
|
|
sftp.DeleteDirectory(path);
|
|
sftp.Disconnect();
|
|
|
|
//using (SftpClient sftp = new SftpClient(server.Ip, server.Port, "root", server.SuPassword))
|
|
//{
|
|
// sftp.Connect();
|
|
// if (sftp.FileExists(path))
|
|
// sftp.Delete(path);
|
|
// b_suc = true;
|
|
//}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Utility.SendLog("", ex.ToString());
|
|
}
|
|
return b_suc;
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|