SuperDesign/Source/RySmartEditor/FTP/FTP_FluentFTP.cs
zilinsoft 993f1ca1a9 ### 2024-12-20 星期五更新
------
#### SuperDesign    V3.0.2412.2001
- *.[新增]新增程序更新日志设置和自动发布功能。
- *.[修复]修复Post数据格式不正确时双击文本框会导致软件闪退的BUG。
2024-12-20 08:15:19 +08:00

313 lines
10 KiB
C#

using FluentFTP;
using FluentFTP.Client.BaseClient;
using GameBackup3H3.DbOp;
using ryCommon;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Net;
using System.Text;
#pragma warning disable CA1031 // 不捕获常规异常类型
namespace FTPop
{
/// <summary>
/// FTP管理
/// </summary>
public class FTPFluentFTP : IFTP, IDisposable
{
private bool disposed = false;
FtpClient conn;
public string CurRemoteFolder { get; private set; } = "";
FTPInfo _ftpinfo;
private Encoding GetEncoding()
{
if (_ftpinfo.Encoding == "UTF8")
{ return Encoding.UTF8; }
else
{ return Encoding.GetEncoding(_ftpinfo.Encoding); }
}
private void AppendText(string text, Color color)
{
}
/// <summary>
/// 打开FTP
/// </summary>
/// <param name="ftpinfo"></param>
public int Open(FTPInfo ftpinfo)
{
if(ftpinfo==null)
{
return -1;
}
_ftpinfo = ftpinfo;
conn = new FtpClient
{
Host = _ftpinfo.IP,
Port = _ftpinfo.Port,
Credentials = new NetworkCredential(_ftpinfo.UserName, _ftpinfo.Pwd)
};
conn.Config.ConnectTimeout = 35000;
conn.Config.DataConnectionConnectTimeout = 35000;
conn.Config.DataConnectionReadTimeout = 35000;
conn.Config.ReadTimeout = 35000;
conn.Config.DataConnectionType = FtpDataConnectionType.AutoPassive;
conn.Config.SslProtocols = System.Security.Authentication.SslProtocols.Tls12;
try
{
if (_ftpinfo.Encrypt > 0)
{
conn.Config.EncryptionMode = _ftpinfo.Encrypt == 2 ? FtpEncryptionMode.Explicit : FtpEncryptionMode.Implicit;
conn.Config.ValidateAnyCertificate = true;
conn.ValidateCertificate += new FtpSslValidation(OnValidateCertificate);
}
conn.Config.DataConnectionEncryption = true;
conn.Connect();
if (conn.IsConnected)
{
ChangeWorkingDirectory("");
//conn.DataConnectionType = FtpDataConnectionType.PASV;
//var ss= conn.GetListing();
}
}
catch(Exception ex)
{
return -2;
}
return conn.IsConnected?1:0;
}
private void AsyncMethod()
{
//var kk = await conn.GetListingAsync();
}
private static void OnValidateCertificate(BaseFtpClient control, FtpSslValidationEventArgs e)
{
if (e.PolicyErrors != System.Net.Security.SslPolicyErrors.None)
{
// invalid cert, do you want to accept it?
e.Accept = true;
}
else
{
e.Accept = true;
}
}
private bool ChangeWorkingDirectory(string Path)
{
if (Path == null || Path.Length == 0)
{
AppendText("Status : Directory Was Not Found\n", Color.Red);
return false;
}
conn.SetWorkingDirectory(Path);
CurRemoteFolder = Path;
AppendText("Status : Current Working Directory is " + CurRemoteFolder + "\n", Color.Red);
return true;
}
/// <summary>
/// 关闭FTP
/// </summary>
/// <returns></returns>
public int Close()
{
conn.Disconnect();
conn.Dispose();
return 1;
}
/// <summary>
/// 移除文件
/// </summary>
/// <param name="remotePath"></param>
/// <returns></returns>
public int RemoveFiles(string remotePath)
{
conn.DeleteFile(remotePath);
return 1;
}
/// <summary>
/// 移动文件
/// </summary>
/// <param name="fromPath"></param>
/// <param name="toPath"></param>
/// <returns></returns>
public int MoveFile(string fromPath, string toPath)
{
conn.Rename(fromPath, toPath);
return 1;
}
/// <summary>
/// 文件是否存在
/// </summary>
/// <param name="remotePath"></param>
/// <returns></returns>
public bool FileExists(string remotePath)
{
return conn.FileExists(remotePath);
}
/// <summary>
/// 文件大小
/// </summary>
/// <param name="remotePath"></param>
/// <returns></returns>
public Int64 FileSize(string remotePath)
{
try
{
return conn.GetFileSize(remotePath);
}
catch { return -1; }
}
/// <summary>
/// 文件最后修改时间
/// </summary>
/// <param name="remotePath"></param>
/// <returns></returns>
public DateTime FileLastWriteTime(string remotePath)
{
try
{
return conn.GetModifiedTime(remotePath);
}
catch { return new DateTime(2000,1,1); }
}
/// <summary>
/// 文件信息
/// </summary>
/// <param name="remotePath"></param>
/// <returns></returns>
public RemoteFileInfo GetFileInfo(string remotePath)
{
try
{
return new RemoteFileInfo()
{
LastWriteTime = conn.GetModifiedTime(remotePath),
Length = conn.GetFileSize(remotePath),
Name = System.IO.Path.GetFileName(remotePath),
IsDirectory = conn.DirectoryExists(remotePath)
};
}
catch
{
return new RemoteFileInfo();
}
}
/// <summary>
/// 显示文件夹列表
/// </summary>
/// <param name="CurFolder"></param>
/// <returns></returns>
public List<RemoteFileInfo> ListDirectory(string CurFolder)
{
//var aa = conn.GetNameListing(CurFolder) ;
List<RemoteFileInfo> list = new List<RemoteFileInfo>();
conn.Encoding = GetEncoding();
var list_conn= conn.GetListing(CurFolder.TrimEnd('/'));
//var list_conn2 = conn.GetNameListing();
for (int i = 0; i < list_conn.Length; i++)
{
var item = list_conn[i];
list.Add(new RemoteFileInfo()
{
FullName = item.FullName,
IsDirectory = item.Type== FtpObjectType.Directory,
Name = item.Name,
Length = item.Size,
LastWriteTime = item.Modified
});
}
return list;
}
/// <summary>
/// 上传
/// </summary>
/// <param name="localPath"></param>
/// <param name="remotePath"></param>
/// <returns></returns>
public int Upload(string localPath, string remotePath)
{
try
{
Action<FtpProgress> progress = delegate (FtpProgress p)
{
var progress2 = new FileTransferProgressEventArgs()
{
Cancel = false,
LocalPath = localPath,
FileProgress = p.Progress/100d,
IsComplete=p.Progress==100,
Speed=p.TransferSpeed
};
FileTransferProgress?.Invoke(this, progress2);
//if (progress2.Cancel) {p.=true ; }
if (p.Progress == 1)
{
// all done!
}
else
{
// percent done = (p.Progress * 100)
}
};
// upload a file with progress tracking
var result= conn.UploadFile(localPath, remotePath, FtpRemoteExists.Overwrite, true, FtpVerify.None, progress);
if (result == FtpStatus.Success)
{
if (FileSize(remotePath) != RyFiles.GetFileSize(localPath))
{
ErrorMsg = "文件上传不完整";
return -1;
}
else
{
return 1;
}
}
return -2;
}
catch (Exception ex)
{
ErrorMsg = ex.Message;
return -1;
}
}
public string ErrorMsg { get; set; } = "";
/// <summary>
/// 文件传输事件
/// </summary>
public event FileTransferProgressEventHandler FileTransferProgress;
~FTPFluentFTP()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
Close();
// If disposing equals true, dispose all managed
// and unmanaged resources.
if (disposing)
{
// Dispose managed resources.
}
// Release unmanaged resources. If disposing is false,
// only the following code is executed.
// Note that this is not thread safe.
// Another thread could start disposing the object
// after the managed resources are disposed,
// but before the disposed flag is set to true.
// If thread safety is necessary, it must be
// implemented by the client.
}
disposed = true;
}
}
}