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 { /// /// FTP管理 /// 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) { } /// /// 打开FTP /// /// 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; } /// /// 关闭FTP /// /// public int Close() { return 1; } int delCount = 0; public int ReTryCount { get; set; } = 2; /// /// 移除文件 /// /// /// 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; } } /// /// 移动文件 /// /// /// /// 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; } /// /// 文件是否存在 /// /// /// public bool FileExists(string remotePath) { long Filesize = FileSize(remotePath); return Filesize>0; } /// /// 文件大小 /// /// /// 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; } /// /// 文件最后修改时间 /// /// /// public DateTime FileLastWriteTime(string remotePath) { return new DateTime(2000, 1, 1); } /// /// 文件信息 /// /// /// public RemoteFileInfo GetFileInfo(string remotePath) { return new RemoteFileInfo(); } /// /// 显示文件夹列表 /// /// /// public List ListDirectory(string CurFolder) { InitWorkingDirectory(); var list = new List(); try { string regex = @"^" + //# Start of line @"(?[\-ld])" + //# File size @"(?[\-rwx]{9})" + //# Whitespace \n @"\s+" + //# Whitespace \n @"(?\d+)" + @"\s+" + //# Whitespace \n @"(?\w+)" + @"\s+" + //# Whitespace \n @"(?\w+)" + @"\s+" + //# Whitespace \n @"(?\d+)" + @"\s+" + //# Whitespace \n @"(?\w{3})" + //# Month (3 letters) \n @"\s+" + //# Whitespace \n @"(?\d{1,2})" + //# Day (1 or 2 digits) \n @"\s+" + //# Whitespace \n @"(?[\d:]{4,5})" + //# Time or year \n @"\s+" + //# Whitespace \n @"(?(.*))" + //# 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; } /// /// 上传 /// /// /// /// 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; } = ""; /// /// 文件传输事件 /// 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; } } }