using Estsh.Client.Common.CostomTraceListener; using Estsh.Client.Common.FileUtil; using FluentFTP; using System.ComponentModel; using System.Diagnostics; using System.Reflection; using Config = System.Configuration.ConfigurationManager; namespace Estsh.Client.Update { public partial class Updater : Form { private const string UPDATER_DIR = "Updater"; private const string COMMON_DIR = "Common"; private const string TEMP_KILL_BAT_FILE = "killmyself.bat"; private string updateDirectory; private string runProgramName; private string args; private bool isRunProgram; private FtpClient ftpClient = null; public Updater(string directory, string fileName, string args) { InitializeComponent(); updateDirectory = directory; runProgramName = fileName; this.args = args; if (Config.AppSettings["HideWindow"].ToLower() == "true") this.WindowState = FormWindowState.Minimized; } private void KillSelfThenRun(string TempDirectory) { string filename = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, TEMP_KILL_BAT_FILE); using (StreamWriter bat = File.CreateText(filename)) { bat.WriteLine(string.Format(@" @echo off if not exist ""{1}\{0}"" goto end :selfkill attrib -a -r -s -h ""{0}"" del ""{0}"" if exist ""{0}"" goto selfkill xcopy /y/s/e/v ""{1}"" ""{0}"" {2} {3} :end del %0 ", AppDomain.CurrentDomain.FriendlyName, TempDirectory, updateDirectory, runProgramName)); } ProcessStartInfo info = new ProcessStartInfo(filename); info.WindowStyle = ProcessWindowStyle.Hidden; Process.Start(info); Environment.Exit(0); } public int Update(string directory) { string fileName = directory + ".xml"; Trace.WriteLine("Download XML File: " + fileName); ftpClient.DownloadFile(fileName, fileName); FileInfos updateInfos = GetUpdateLists(directory); Trace.WriteLine(updateInfos.Infos.Count + " Files Need Upgrade, TotalBytes: " + updateInfos.TotalBytes); foreach (var fi in updateInfos.Infos) { Trace.WriteLine("Download File: " + fi.Name + ", Size: " + fi.Size + ", Version: " + fi.Version); if (directory != UPDATER_DIR) { // 把所有的程序下载到一个目录,便于共享 ftpClient.DownloadFile(Path.GetFileName(fi.Name), fi.Name); } else { CheckDirectory(fi.Name); ftpClient.DownloadFile(fi.Name, fi.Name); } } Trace.WriteLine("Delete XML File: " + fileName); File.Delete(fileName); return updateInfos.Infos.Count; } /// /// 获取要更新的文件列表 /// /// /// public FileInfos GetUpdateLists(string directory) { FileInfos serverInfos = FileManager.LoadXmlFileLists(directory + ".xml"); FileInfos localInfos = FileManager.GetLocalFileInfo(serverInfos); return FileManager.GetUpdateFileLists(serverInfos, localInfos); } private void CheckDirectory(string fileName) { string currentPath = AppDomain.CurrentDomain.BaseDirectory; string[] path = new string[10]; path = fileName.Split('/'); for (int i = 0; i < path.Length - 1; i++) { currentPath = currentPath + "/" + path[i]; if (!Directory.Exists(currentPath)) { Directory.CreateDirectory(currentPath); } } } private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { try { string host = Config.AppSettings["FileServerIP"].ToString(); int port = int.Parse(Config.AppSettings["FileServerPort"].ToString()); string userName = Config.AppSettings["UserName"].ToString(); string password = Config.AppSettings["Password"].ToString(); string tempUpdateFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, UPDATER_DIR); tempUpdateFile = Path.Combine(tempUpdateFile, AppDomain.CurrentDomain.FriendlyName); ftpClient = new FtpClient(host, port, userName, password); ftpClient.Connect(); // 更新公共目录 Update(COMMON_DIR); if (Update(UPDATER_DIR) == 0) { Update(updateDirectory); ftpClient.Disconnect(); isRunProgram = true; } else { ftpClient.Disconnect(); isRunProgram = false; } } catch (Exception ex) { MessageBox.Show(ex.ToString(), ex.Message, MessageBoxButtons.OK, MessageBoxIcon.Error); } finally { if (ftpClient != null) { ftpClient.Disconnect(); ftpClient.Dispose(); ftpClient = null; } } } private void Updater_Load(object sender, EventArgs e) { this.Text = this.Text + " Ver: " + Assembly.GetExecutingAssembly().GetName().Version.ToString(); Trace.Listeners.Add(new RichTextBoxTraceListener(rtbState, 1000)); while (backgroundWorker1.IsBusy) Application.DoEvents(); backgroundWorker1.RunWorkerAsync(); } private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { if (isRunProgram) { string runPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, runProgramName); Trace.WriteLine("Start Program: " + runPath); Process.Start(runProgramName, args); Environment.Exit(0); } else { Trace.WriteLine("Upgrade Myself Then Reboot."); KillSelfThenRun(UPDATER_DIR); } } private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) { } } }