------ #### SuperDesign V3.0.2412.2001 - *.[新增]新增程序更新日志设置和自动发布功能。 - *.[修复]修复Post数据格式不正确时双击文本框会导致软件闪退的BUG。
460 lines
18 KiB
C#
460 lines
18 KiB
C#
using GameBackup3H3.DbOp;
|
|
using ryCommon;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Drawing;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Net;
|
|
using System.Net.Security;
|
|
using System.Net.Sockets;
|
|
using System.Security.Cryptography.X509Certificates;
|
|
using System.Text;
|
|
using System.Text.RegularExpressions;
|
|
using WinSCP;
|
|
#pragma warning disable CA1031 // 不捕获常规异常类型
|
|
namespace FTPop
|
|
{
|
|
/// <summary>
|
|
/// FTP管理
|
|
/// </summary>
|
|
public class FTPFtpWeb : IFTP, IDisposable
|
|
{
|
|
private bool disposed = false;
|
|
string ftpURI;
|
|
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 static bool OnCertificateValidation(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
|
|
{
|
|
/* Console.WriteLine("Server Certificate Issued To: {0}", certificate.GetName());
|
|
|
|
Console.WriteLine("Server Certificate Issued By: {0}", certificate.GetIssuerName());
|
|
|
|
|
|
// Return true if there are no policy errors
|
|
|
|
// The certificate can also be manually verified to
|
|
|
|
//make sure it meets your specific // policies by
|
|
|
|
// interrogating the x509Certificate object.
|
|
|
|
if (errors != SslPolicyErrors.None)
|
|
{
|
|
Console.WriteLine("Server Certificate Validation Error");
|
|
|
|
Console.WriteLine(errors.ToString());
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
else
|
|
{
|
|
Console.WriteLine("No Certificate Validation Errors");
|
|
|
|
return true;
|
|
|
|
}*/
|
|
return true; //所有證書都合法
|
|
|
|
}
|
|
|
|
private void ShowCertificateInfo(X509Certificate remoteCertificate, bool verbose)
|
|
{
|
|
//Console.WriteLine("Certficate Information for:/n{0}/n", remoteCertificate.GetName());
|
|
//Console.WriteLine("Valid From: /n{0}", remoteCertificate.GetEffectiveDateString());
|
|
//Console.WriteLine("Valid To: /n{0}", remoteCertificate.GetExpirationDateString());
|
|
//Console.WriteLine("Certificate Format: /n{0}/n", remoteCertificate.GetFormat());
|
|
|
|
//Console.WriteLine("Issuer Name: /n{0}", remoteCertificate.GetIssuerName());
|
|
|
|
//if (verbose)
|
|
//{
|
|
// Console.WriteLine("Serial Number: /n{0}", remoteCertificate.GetSerialNumberString());
|
|
// Console.WriteLine("Hash: /n{0}", remoteCertificate.GetCertHashString());
|
|
// Console.WriteLine("Key Algorithm: /n{0}", remoteCertificate.GetKeyAlgorithm());
|
|
// Console.WriteLine("Key Algorithm Parameters: /n{0}", remoteCertificate.GetKeyAlgorithmParametersString());
|
|
// Console.WriteLine("Public Key: /n{0}", remoteCertificate.GetPublicKeyString());
|
|
//}
|
|
}
|
|
private void showSslInfo(string serverName, SslStream sslStream, bool verbose)
|
|
{
|
|
ShowCertificateInfo(sslStream.RemoteCertificate, verbose);
|
|
|
|
Console.WriteLine("/n/nSSL Connect Report for : {0}/n", serverName);
|
|
Console.WriteLine("Is Authenticated: {0}", sslStream.IsAuthenticated);
|
|
Console.WriteLine("Is Encrypted: {0}", sslStream.IsEncrypted);
|
|
Console.WriteLine("Is Signed: {0}", sslStream.IsSigned);
|
|
Console.WriteLine("Is Mutually Authenticated: {0}/n", sslStream.IsMutuallyAuthenticated);
|
|
|
|
Console.WriteLine("Hash Algorithm: {0}", sslStream.HashAlgorithm);
|
|
Console.WriteLine("Hash Strength: {0}", sslStream.HashStrength);
|
|
Console.WriteLine("Cipher Algorithm: {0}", sslStream.CipherAlgorithm);
|
|
Console.WriteLine("Cipher Strength: {0}/n", sslStream.CipherStrength);
|
|
|
|
Console.WriteLine("Key Exchange Algorithm: {0}", sslStream.KeyExchangeAlgorithm);
|
|
Console.WriteLine("Key Exchange Strength: {0}/n", sslStream.KeyExchangeStrength);
|
|
Console.WriteLine("SSL Protocol: {0}", sslStream.SslProtocol);
|
|
}
|
|
private X509CertificateCollection _clientCertificates = new X509CertificateCollection();
|
|
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;
|
|
AppendText("Status : Connected to " + ftpinfo.IP + "\n", Color.Red);
|
|
InitWorkingDirectory();
|
|
return 1;
|
|
}
|
|
private bool InitWorkingDirectory()
|
|
{
|
|
ftpURI = "ftp://" + _ftpinfo.IP+":"+_ftpinfo.Port + "/";
|
|
return true;
|
|
}
|
|
/// <summary>
|
|
/// 关闭FTP
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public int Close()
|
|
{
|
|
return 1;
|
|
}
|
|
int delCount = 0;
|
|
public int ReTryCount { get; set; } = 2;
|
|
/// <summary>
|
|
/// 移除文件
|
|
/// </summary>
|
|
/// <param name="remotePath"></param>
|
|
/// <returns></returns>
|
|
public int RemoveFiles(string remotePath)
|
|
{
|
|
InitWorkingDirectory();
|
|
try
|
|
{
|
|
string uri = ftpURI + remotePath;
|
|
FtpWebRequest reqFTP;
|
|
reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri));
|
|
reqFTP.Credentials = new NetworkCredential(_ftpinfo.UserName, _ftpinfo.Pwd);
|
|
reqFTP.KeepAlive = false;
|
|
reqFTP.Timeout = 3000;
|
|
reqFTP.Method = WebRequestMethods.Ftp.DeleteFile;
|
|
ServicePoint currentServicePoint = reqFTP.ServicePoint;
|
|
currentServicePoint.ConnectionLimit = 1024;
|
|
string result = String.Empty;
|
|
FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
|
|
long size = response.ContentLength;
|
|
Stream datastream = response.GetResponseStream();
|
|
StreamReader sr = new StreamReader(datastream);
|
|
result = sr.ReadToEnd();
|
|
sr.Close();
|
|
datastream.Close();
|
|
response.Close();
|
|
delCount = 0;
|
|
return 1;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
|
|
delCount++;
|
|
if (delCount <= ReTryCount)
|
|
{
|
|
return RemoveFiles(remotePath);
|
|
}
|
|
else
|
|
{
|
|
delCount = 0;
|
|
}
|
|
AppendText("Delete Error --> " + ex.Message + " 文件名:" + remotePath, Color.Red);
|
|
//Insert_Standard_ErrorLog.Insert("FtpWeb", "Delete Error --> " + ex.Message + " 文件名:" + fileName);
|
|
return -1;
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// 移动文件
|
|
/// </summary>
|
|
/// <param name="fromPath"></param>
|
|
/// <param name="toPath"></param>
|
|
/// <returns></returns>
|
|
public int MoveFile(string fromPath, string toPath)
|
|
{
|
|
FtpWebRequest reqFTP;
|
|
try
|
|
{
|
|
reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(ftpURI + fromPath));
|
|
reqFTP.Method = WebRequestMethods.Ftp.Rename;
|
|
reqFTP.RenameTo = toPath;
|
|
reqFTP.UseBinary = true;
|
|
reqFTP.KeepAlive = false;
|
|
reqFTP.Timeout = 10000;
|
|
reqFTP.Credentials = new NetworkCredential(_ftpinfo.UserName, _ftpinfo.Pwd);
|
|
ServicePoint currentServicePoint = reqFTP.ServicePoint;
|
|
currentServicePoint.ConnectionLimit = 1024;
|
|
FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
|
|
Stream ftpStream = response.GetResponseStream();
|
|
ftpStream.Close();
|
|
response.Close();
|
|
}
|
|
catch (Exception)
|
|
{
|
|
return -1;
|
|
}
|
|
return 1;
|
|
}
|
|
/// <summary>
|
|
/// 文件是否存在
|
|
/// </summary>
|
|
/// <param name="remotePath"></param>
|
|
/// <returns></returns>
|
|
public bool FileExists(string remotePath)
|
|
{
|
|
long Filesize = FileSize(remotePath);
|
|
return Filesize>0;
|
|
}
|
|
/// <summary>
|
|
/// 文件大小
|
|
/// </summary>
|
|
/// <param name="remotePath"></param>
|
|
/// <returns></returns>
|
|
public Int64 FileSize(string remotePath)
|
|
{
|
|
FtpWebRequest reqFTP;
|
|
long fileSize;
|
|
try
|
|
{
|
|
reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(ftpURI + remotePath));
|
|
reqFTP.Method = WebRequestMethods.Ftp.GetFileSize;
|
|
reqFTP.UseBinary = true;
|
|
reqFTP.KeepAlive = false;
|
|
reqFTP.Timeout = 10000;
|
|
reqFTP.Credentials = new NetworkCredential(_ftpinfo.UserName, _ftpinfo.Pwd);
|
|
ServicePoint currentServicePoint = reqFTP.ServicePoint;
|
|
currentServicePoint.ConnectionLimit = 1024;
|
|
FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
|
|
Stream ftpStream = response.GetResponseStream();
|
|
fileSize = response.ContentLength;
|
|
ftpStream.Close();
|
|
response.Close();
|
|
}
|
|
catch (Exception)
|
|
{
|
|
return -1;
|
|
}
|
|
return fileSize;
|
|
}
|
|
/// <summary>
|
|
/// 文件最后修改时间
|
|
/// </summary>
|
|
/// <param name="remotePath"></param>
|
|
/// <returns></returns>
|
|
public DateTime FileLastWriteTime(string remotePath)
|
|
{
|
|
return new DateTime(2000, 1, 1);
|
|
}
|
|
/// <summary>
|
|
/// 文件信息
|
|
/// </summary>
|
|
/// <param name="remotePath"></param>
|
|
/// <returns></returns>
|
|
public RemoteFileInfo GetFileInfo(string remotePath)
|
|
{
|
|
return new RemoteFileInfo();
|
|
}
|
|
/// <summary>
|
|
/// 显示文件夹列表
|
|
/// </summary>
|
|
/// <param name="CurFolder"></param>
|
|
/// <returns></returns>
|
|
public List<RemoteFileInfo> ListDirectory(string CurFolder)
|
|
{
|
|
InitWorkingDirectory();
|
|
var list = new List<RemoteFileInfo>();
|
|
try
|
|
{
|
|
string regex =
|
|
@"^" + //# Start of line
|
|
@"(?<dir>[\-ld])" + //# File size
|
|
@"(?<permission>[\-rwx]{9})" + //# Whitespace \n
|
|
@"\s+" + //# Whitespace \n
|
|
@"(?<filecode>\d+)" +
|
|
@"\s+" + //# Whitespace \n
|
|
@"(?<owner>\w+)" +
|
|
@"\s+" + //# Whitespace \n
|
|
@"(?<group>\w+)" +
|
|
@"\s+" + //# Whitespace \n
|
|
@"(?<size>\d+)" +
|
|
@"\s+" + //# Whitespace \n
|
|
@"(?<month>\w{3})" + //# Month (3 letters) \n
|
|
@"\s+" + //# Whitespace \n
|
|
@"(?<day>\d{1,2})" + //# Day (1 or 2 digits) \n
|
|
@"\s+" + //# Whitespace \n
|
|
@"(?<timeyear>[\d:]{4,5})" + //# Time or year \n
|
|
@"\s+" + //# Whitespace \n
|
|
@"(?<filename>(.*))" + //# Filename \n
|
|
@"$"; //# End of line
|
|
StringBuilder result = new StringBuilder();
|
|
FtpWebRequest ftp;
|
|
ftp = (FtpWebRequest)FtpWebRequest.Create(new Uri(ftpURI + CurFolder));
|
|
ftp.Credentials = new NetworkCredential(_ftpinfo.UserName, _ftpinfo.Pwd);
|
|
ftp.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
|
|
ftp.KeepAlive = false;
|
|
ftp.Timeout = 10000;
|
|
if (_ftpinfo.Encrypt > 0)
|
|
{
|
|
ServicePointManager.ServerCertificateValidationCallback = new
|
|
System.Net.Security.RemoteCertificateValidationCallback(OnCertificateValidation);
|
|
ftp.ClientCertificates = new X509CertificateCollection();
|
|
ftp.AuthenticationLevel = AuthenticationLevel.MutualAuthRequested;
|
|
ftp.ImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Identification;
|
|
ftp.EnableSsl = true;
|
|
}
|
|
WebResponse response = ftp.GetResponse();
|
|
StreamReader reader = new StreamReader(response.GetResponseStream(), GetEncoding());
|
|
string line = reader.ReadLine();
|
|
while (line != null)
|
|
{
|
|
var split = new Regex(regex).Match(line);
|
|
string dir = split.Groups["dir"].ToString();
|
|
string filename = split.Groups["filename"].ToString();
|
|
var size = split.Groups["size"].ToString();
|
|
bool isDirectory = !string.IsNullOrWhiteSpace(dir) && dir.Equals("d", StringComparison.OrdinalIgnoreCase);
|
|
list.Add(new RemoteFileInfo()
|
|
{
|
|
FullName = CurFolder.TrimEnd('/') +"/"+ filename,
|
|
IsDirectory = isDirectory,
|
|
Name = filename,
|
|
Length = size.ToInt64(),
|
|
LastWriteTime = (split.Groups["timeyear"].ToString() + " " + split.Groups["month"].ToString() + " " + split.Groups["day"].ToString()).ToDateTime()
|
|
}) ;
|
|
result.Append(line);
|
|
result.Append("\n");
|
|
line = reader.ReadLine();
|
|
}
|
|
result.Remove(result.ToString().LastIndexOf("\n", StringComparison.OrdinalIgnoreCase), 1);
|
|
reader.Close();
|
|
response.Close();
|
|
}
|
|
catch (Exception)
|
|
{
|
|
return list;
|
|
}
|
|
return list;
|
|
}
|
|
/// <summary>
|
|
/// 上传
|
|
/// </summary>
|
|
/// <param name="localPath"></param>
|
|
/// <param name="remotePath"></param>
|
|
/// <returns></returns>
|
|
public int Upload(string localPath, string remotePath)
|
|
{
|
|
FileInfo fileInf = new FileInfo(localPath);
|
|
string uri = ftpURI + remotePath;
|
|
FtpWebRequest reqFTP;
|
|
reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri));
|
|
reqFTP.Credentials = new NetworkCredential(_ftpinfo.UserName, _ftpinfo.Pwd);
|
|
reqFTP.KeepAlive = true;
|
|
reqFTP.Method = WebRequestMethods.Ftp.UploadFile;
|
|
reqFTP.UseBinary = true;
|
|
reqFTP.ContentLength = fileInf.Length;
|
|
reqFTP.EnableSsl = true;
|
|
ServicePoint currentServicePoint = reqFTP.ServicePoint;
|
|
currentServicePoint.ConnectionLimit = 1024;
|
|
int buffLength = 2048;
|
|
byte[] buff = new byte[buffLength];
|
|
int contentLen;
|
|
FileStream fs = fileInf.OpenRead();
|
|
Int64 upload_size = 0;
|
|
try
|
|
{
|
|
Stream strm = reqFTP.GetRequestStream();
|
|
contentLen = fs.Read(buff, 0, buffLength);
|
|
while (contentLen != 0)
|
|
{
|
|
double process = upload_size / (double)fileInf.Length;
|
|
if (process > 1) { process = 1; }
|
|
var progress = new FileTransferProgressEventArgs()
|
|
{
|
|
Cancel = false,
|
|
LocalPath = localPath,
|
|
FileProgress = process,
|
|
};
|
|
FileTransferProgress?.Invoke(this, progress);
|
|
if (progress.Cancel) { break; }
|
|
upload_size += buffLength;
|
|
strm.Write(buff, 0, contentLen);
|
|
contentLen = fs.Read(buff, 0, buffLength);
|
|
}
|
|
strm.Close();
|
|
fs.Close();
|
|
var progress2 = new FileTransferProgressEventArgs()
|
|
{
|
|
Cancel = false,
|
|
LocalPath = localPath,
|
|
FileProgress = 1,
|
|
IsComplete=true
|
|
};
|
|
FileTransferProgress?.Invoke(this, progress2);
|
|
return 1;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
ErrorMsg = ex.Message;
|
|
return -1;
|
|
}
|
|
}
|
|
public string ErrorMsg { get; set; } = "";
|
|
/// <summary>
|
|
/// 文件传输事件
|
|
/// </summary>
|
|
public event FileTransferProgressEventHandler FileTransferProgress;
|
|
~FTPFtpWeb()
|
|
{
|
|
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;
|
|
}
|
|
}
|
|
}
|