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)
{
}
}
}