AIMS/AIMSAutoUpdate/FTPTransmission.cs
2023-03-01 00:21:03 +08:00

450 lines
18 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Windows.Forms;
using System.Security.Cryptography;
using System.Collections;
using System.Xml.Linq;
using System.Reflection;
namespace AIMSAutoUpdate
{
/// <summary>
/// ftp下载类
/// </summary>
public class FTPTransmission
{
/// <summary>
/// 记录所有要下载的文件路径及下载到本地的路径
/// </summary>
public static List<ftpFileDirectory> ListFileDirectory = new List<ftpFileDirectory>();
/// <summary>
/// 记录当前文件路径及下载到本地的路径
/// </summary>
public static List<ftpFileDirectory> nowListFileDirectory = new List<ftpFileDirectory>();
/// <summary>
/// 记录要下载的文件路径及下载到本地的路径
/// </summary>
public struct ftpFileDirectory
{
/// <summary>
/// 要下载的文件路径
/// </summary>
public string ftpPath;
/// <summary>
/// 下载到本地的路径
/// </summary>
public string localPath;
/// <summary>
/// 文件名
/// </summary>
public string filename;
/// <summary>
/// 文件大小
/// </summary>
public long filelength;
/// <summary>
/// MD5码
/// </summary>
public string MD5Hash;
}
/// <summary>
/// 设置ftp服务器的命令并获取文件和文件夹以及文件夹内的子文件
/// </summary>
/// <param name="ftpads">FTP地址路径</param>
/// <param name="type">要发送到FTP服务器的命令</param>
/// <param name="username">用户名</param>
/// <param name="password">密码</param>
/// <returns></returns>
public static string[] ftp(string ftpads, string type, string username, string password, string encoding)
{
WebResponse webresp = null;
StreamReader ftpFileListReader = null;
FtpWebRequest ftpRequest = null;
try
{
ftpRequest = (FtpWebRequest)WebRequest.Create(new Uri(ftpads));
ftpRequest.Method = type;
ftpRequest.UsePassive = false;//只需要添加这一句话
ftpRequest.Credentials = new NetworkCredential(username,
password);
webresp = ftpRequest.GetResponse();
if (encoding == "Default")
{
ftpFileListReader = new StreamReader(webresp.GetResponseStream(), Encoding.Default);
}
else
{
ftpFileListReader = new StreamReader(webresp.GetResponseStream(), Encoding.UTF8);
}
StringBuilder str = new StringBuilder();
string line = ftpFileListReader.ReadLine();
while (line != null)
{
str.Append(line);
str.Append("\n");
line = ftpFileListReader.ReadLine();
}
string[] fen = str.ToString().Split('\n');
return fen;
}
catch (Exception )
{
MessageBox.Show("更新失败! 请检查网络或者FTP用户名与口令!");
Environment.Exit(0);
return null;
}
}
/// <summary>
/// 递归实现获取ftp目录下所有文件及文件夹以及文件夹内的子文件
/// </summary>
/// <param name="ftpads">FTP路径</param>
/// <param name="downloadDir">保存的本地路径</param>
/// <param name="username">用户名</param>
/// <param name="password">密码</param>
public static void downftp(string ftpads, string downloadDir, string username, string password, Hashtable htUpdateFile, string encoding)
{
try
{
downloadDir = downloadDir.Replace("\\\\", "\\");
string ftpdir = ftpads;
string[] fullname = ftp(ftpads, WebRequestMethods.Ftp.ListDirectoryDetails, username, password, encoding);
if (fullname == null) return;
string[] onlyname = ftp(ftpads, WebRequestMethods.Ftp.ListDirectory, username, password, encoding);
if (onlyname == null) return;
if (!Directory.Exists(downloadDir))
{
Directory.CreateDirectory(downloadDir);
}
foreach (string names in fullname)
{
//判断是否具有文件夹标识<DIR>
if (names.Contains("<DIR>"))
{
string olname = names.Split(new string[] { "<DIR>" },
StringSplitOptions.None)[1].Trim();
downftp(ftpads + "/" + olname, downloadDir + "\\" + olname, username, password, htUpdateFile, encoding);
}
else
{
foreach (string onlynames in onlyname)
{
if (string.IsNullOrEmpty(onlynames.Trim()) || string.IsNullOrEmpty(names.Trim())) break;
if (names.Contains(" " + onlynames))
{
//download(downloadDir + "\\" + onlynames, ftpads + "/" + onlynames, username, password);
var fd = new ftpFileDirectory();
fd.ftpPath = ftpads + "/" + onlynames.ToString();
fd.localPath = downloadDir + "\\" + onlynames.ToString();
fd.localPath = fd.localPath.Replace("\\\\", "\\");
fd.filename = onlynames.ToString();
fd.filelength = GetFileSize(fd.ftpPath, username, password);
for (int i = 0; i < htUpdateFile.Count; i++)
{
string[] fileArray = (string[])htUpdateFile[i];
if (fd.filename == fileArray[0])
{
fd.MD5Hash = fileArray[1];
break;
}
}
ListFileDirectory.Add(fd);
break;
}
}
}
}
}
catch (Exception ex)
{
MessageBox.Show("获取目录失败+downftp" + ex.ToString());
Environment.Exit(0);
}
}
/// <summary>
/// 递归实现获取ftp目录下所有文件及文件夹以及文件夹内的子文件
/// </summary>
/// <param name="ftpads">FTP路径</param>
/// <param name="downloadDir">保存的本地路径</param>
/// <param name="username">用户名</param>
/// <param name="password">密码</param>
public static void downNow(string ftpads)
{
try
{
DirectoryInfo theFolder = new DirectoryInfo(ftpads);
printAllFile(theFolder);
}
catch (Exception ex)
{
MessageBox.Show("获取目录失败+downftp" + ex.ToString());
Environment.Exit(0);
}
}
public static void printAllFile(DirectoryInfo di)
{
FileInfo[] fiArray = di.GetFiles();
DirectoryInfo[] diArray = di.GetDirectories();
foreach (FileInfo NextFile in fiArray)
{
if (NextFile.Name.Contains("AIMSAutoUpdate") || NextFile.Name.Contains("AIMS")) continue;
var fd = new ftpFileDirectory();
fd.ftpPath = NextFile.DirectoryName + "\\" + NextFile.Name.ToString();
fd.filename = NextFile.Name.ToString();
fd.filelength = NextFile.Length;
fd.MD5Hash = GetMD5HashFromFile(fd.ftpPath);
nowListFileDirectory.Add(fd);
}
foreach (DirectoryInfo inst in diArray)
{
printAllFile(inst);
}
}
/// <summary>
/// 单个文件下载
/// </summary>
/// <param name="adss">保存文件的本地路径</param>
/// <param name="ftpadss">下载文件的FTP路径</param>
/// <param name="username">用户名</param>
/// <param name="password">密码</param>
public static void download(string adss, string ftpadss, string username, string password)
{
//FileMode常数确定如何打开或创建文件,指定操作系统应创建新文件。
//FileMode.Create如果文件已存在它将被改写
FileStream outputStream = new FileStream(adss, FileMode.Create);
FtpWebRequest downRequest = (FtpWebRequest)WebRequest.Create(new Uri(ftpadss));
downRequest.Credentials = new NetworkCredential(username, password);
downRequest.UsePassive = false;//只需要添加这一句话
//设置要发送到 FTP 服务器的命令
downRequest.Method = WebRequestMethods.Ftp.DownloadFile;
FtpWebResponse response = (FtpWebResponse)downRequest.GetResponse();
Stream ftpStream = response.GetResponseStream();
long cl = response.ContentLength;
int bufferSize = 2048;
int readCount;
byte[] buffer = new byte[bufferSize];
readCount = ftpStream.Read(buffer, 0, bufferSize);
while (readCount > 0)
{
outputStream.Write(buffer, 0, readCount);
readCount = ftpStream.Read(buffer, 0, bufferSize);
}
ftpStream.Close();
outputStream.Close();
response.Close();
}
/// <summary>
/// 获得文件大小
/// </summary>
/// <param name="filename"></param>
/// <returns></returns>
public static long GetFileSize(string ftpadss, string username, string password)
{
long fileSize = 0;
try
{
FtpWebRequest downRequest = (FtpWebRequest)WebRequest.Create(new Uri(ftpadss));
downRequest.Credentials = new NetworkCredential(username, password);
downRequest.Method = WebRequestMethods.Ftp.GetFileSize;
downRequest.UsePassive = false;//只需要添加这一句话
FtpWebResponse response = (FtpWebResponse)downRequest.GetResponse();
fileSize = response.ContentLength;
response.Close();
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
return fileSize;
}
/// <summary>
/// FTP获取文件的MD5码
/// </summary>
/// <param name="fileName">传入的文件名(含路径及后缀名)</param>
/// <returns></returns>
public static string FTPGetMD5HashFromFile(string fileName)
{
try
{
FileStream file = new FileStream(fileName, System.IO.FileMode.Open);
MD5 md5 = new MD5CryptoServiceProvider();
byte[] retVal = md5.ComputeHash(file);
file.Close();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < retVal.Length; i++)
{
sb.Append(retVal[i].ToString("x2"));
}
return sb.ToString();
}
catch (Exception)
{
return "";
//throw new Exception("GetMD5HashFromFile() fail,error:" + ex.Message);
}
}
/// <summary>
/// 获取文件的MD5码
/// </summary>
/// <param name="fileName">传入的文件名(含路径及后缀名)</param>
/// <returns></returns>
public static string GetMD5HashFromFile(string fileName)
{
try
{
FileStream file = new FileStream(fileName, System.IO.FileMode.Open);
MD5 md5 = new MD5CryptoServiceProvider();
byte[] retVal = md5.ComputeHash(file);
file.Close();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < retVal.Length; i++)
{
sb.Append(retVal[i].ToString("x2"));
}
return sb.ToString();
}
catch (Exception)
{
return "";
//throw new Exception("GetMD5HashFromFile() fail,error:" + ex.Message);
}
}
public static void UpdateListXML()
{
try
{
string localXmlFile = AppDomain.CurrentDomain.BaseDirectory + "\\UpdateList.xml";
if (!File.Exists(localXmlFile))
return;
XElement xe = XElement.Load(localXmlFile);
//获取本地EXE版本号
Assembly currentAssembly = Assembly.LoadFile(Application.ExecutablePath.Trim());
AssemblyName CurrentAssemblyName = currentAssembly.GetName();
string Version = CurrentAssemblyName.Version.ToString();
Version vs = new Version(Version);
Version newvs = new Version(xe.Element("Version").Value);
if (vs.CompareTo(newvs) > 0)
{
xe.Element("Version").Value = Version;
FTPTransmission.downNow(AppDomain.CurrentDomain.BaseDirectory);
IEnumerable<XElement> element = from ex in xe.Elements("Files")
select ex;
///删除指定的元素,并保存
if (element.Count() > 0)
{
element.Remove();
}
XElement record = new XElement("Files");
foreach (var item in FTPTransmission.nowListFileDirectory)
{
if (item.filename.Contains("AIMSAutoUpdate")) continue;
FTPTransmission.ftpFileDirectory f = item;
XElement file = new XElement(
new XElement("File",
//new XAttribute("Ver", Version),
new XAttribute("Name", item.filename),
new XAttribute("MD5Hash", item.MD5Hash)));
record.Add(file);
}
xe.Add(record);
xe.Save(localXmlFile);
}
}
catch (Exception)
{
return;
}
}
public static Encoding GetEncoding(string filePath)
{
if (filePath == null)
{
throw new ArgumentNullException("filePath");
}
Encoding encoding1 = Encoding.Default;
if (File.Exists(filePath))
{
try
{
using (FileStream stream1 = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
if (stream1.Length > 0)
{
using (StreamReader reader1 = new StreamReader(stream1, true))
{
char[] chArray1 = new char[1];
reader1.Read(chArray1, 0, 1);
encoding1 = reader1.CurrentEncoding;
reader1.BaseStream.Position = 0;
if (encoding1 == Encoding.UTF8)
{
byte[] buffer1 = encoding1.GetPreamble();
if (stream1.Length >= buffer1.Length)
{
byte[] buffer2 = new byte[buffer1.Length];
stream1.Read(buffer2, 0, buffer2.Length);
for (int num1 = 0; num1 < buffer2.Length; num1++)
{
if (buffer2[num1] != buffer1[num1])
{
encoding1 = Encoding.Default;
break;
}
}
}
else
{
encoding1 = Encoding.Default;
}
}
}
}
}
}
catch (Exception)
{
throw;
}
if (encoding1 == null)
{
encoding1 = Encoding.UTF8;
}
}
return encoding1;
}
}
}