WinFormTools/Update/Form1.cs

337 lines
13 KiB
C#
Raw Normal View History

2022-06-14 23:02:55 +08:00
using DevExpress.XtraEditors;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Updater.Core;
namespace Update
{
public partial class Form1 : DevExpress.XtraEditors.XtraForm
{
//主程序传入的参数,系统标示 是否需要重新启动主程序
private string[] args;
//表示主程序打开时传入的参数
private readonly static string OPEN_FLAG = "121";
private bool isComplete = true;
private UpdateClass updater;
private List<Manifest> mList = new List<Manifest>();
private int mLen = 0;
public Form1()
{
InitializeComponent();
}
private void simpleButton1_Click(object sender, EventArgs e)
{
}
private void simpleButton1_Click_1(object sender, EventArgs e)
{
for (int i = 0; i <= 100; i++)
{
System.Threading.Thread.Sleep(10);
//progressBarControl1.PerformStep();
progressBarControl1.Position = i;
lab_percent.Text = i + "%";
//progressBarControl1.EditValue = i + 1;
//处理当前消息队列中的所有windows消息,不然进度条会不同步
System.Windows.Forms.Application.DoEvents();
}
}
private void Form1_Load(object sender, EventArgs e)
{
try
{
updater = new UpdateClass();
updater.ActivationCompleted += new EventHandler<ActivationCompletedEventArgs>(ActivationCompleted);
updater.ActivationError += new EventHandler<FileCopyErrorEventArgs>(ActivationError);
updater.ActivationInitializing += new EventHandler<ManifestEventArgs>(ActivationInitializing);
updater.ActivationProgressChanged += new EventHandler<FileCopyProgressChangedEventArgs>(ActivationProgressChanged);
updater.ActivationStarted += new EventHandler<ActivationStartedEventArgs>(ActivationStarted);
updater.DownloadCompleted += new EventHandler<DownloadCompleteEventArgs>(DownloadCompleted);
updater.DownloadError += new EventHandler<DownloadErrorEventArgs>(DownloadError);
updater.DownloadProgressChanged += new EventHandler<DownloadProgressEventArgs>(DownloadProgressChanged);
InitUpdater();
}
catch (Exception ex)
{
Log.Write("更新错误:" + ex.Message);
XtraMessageBox.Show("更新错误", "系统提示");
}
}
void ActivationCompleted(object sender, ActivationCompletedEventArgs e)
{
//安装完成
isComplete = true;
lab_filename.Text = "安装完成";
lab_percent.Text = "100%";
if (progressBarControl1.Position != 100)
{
progressBarControl1.Position = 100;
}
if (e.Error != null)
{
lab_filename.Text += ",但出现错误";
lab_filename.Update();
}
else
{
lab_filename.Update();
System.Threading.Thread.Sleep(3000);
string filename = GetFileName(e.Manifest.MyApplication.Location, e.Manifest.MyApplication.EntryPoint.File);
Startup(filename, e.Manifest.MyApplication.EntryPoint.Parameters);
//if (args != null && args.Length > 0)
{
Exit();
}
}
}
private string GetFileName(string location, string file)
{
return Path.Combine(Path.GetFullPath(location), file);
}
void ActivationError(object sender, FileCopyErrorEventArgs e)
{
Log.Write("安装过程中出现错误,错误描述:" + e.Error.Message + System.Environment.NewLine + "Version:" + e.Manifest.Version);
XtraMessageBox.Show(this, "安装错误:" + e.Error.Message, "系统提示");
lab_filename.Text = "系统正在回滚";
updater.Rollback(e.Manifest);
}
void ActivationInitializing(object sender, ManifestEventArgs e)
{
lab_filename.Text = "正在初始化安装,请稍后......";
lab_filename.Update();
lab_percent.Text = "0%";
lab_percent.Update();
lab_fileinfo.Text = "";
lab_fileinfo.Update();
//progressBar1.Value = 0;
}
void ActivationProgressChanged(object sender, FileCopyProgressChangedEventArgs e)
{
progressBarControl1.Position = e.ProgressPercentage;
lab_percent.Text = e.ProgressPercentage.ToString() + "%";
lab_percent.Update();
lab_fileinfo.Text = string.Format("字节数:{0}/{1}", e.BytesToCopy, e.TotalBytesToCopy);
lab_fileinfo.Update();
lab_filename.Text = "正在安装:" + e.SourceFileName;
lab_filename.Update();
}
void ActivationStarted(object sender, ActivationStartedEventArgs e)
{
lab_filename.Text = "开始安装,请稍后......";
lab_filename.Update();
e.Cancel = CheckActivation();
if (e.Cancel)
{
lab_filename.Text = "安装已被取消";
isComplete = true;
}
}
private bool CheckActivation()
{
bool cancel = false;
//检查主程序(进程名称)是否打开,如果打开则提示
string[] processName = { "Client", "Server" };
foreach (string name in processName)
{
System.Diagnostics.Process[] processes = System.Diagnostics.Process.GetProcessesByName(name);
if (processes != null && processes.Length != 0)
{
if (XtraMessageBox.Show(string.Format("进程{0}正在运行中,请关闭后重试。", name), "系统提示",
MessageBoxButtons.RetryCancel, MessageBoxIcon.Information) == System.Windows.Forms.DialogResult.Cancel)
{
cancel = true;
break;
}
else
{
return CheckActivation();
}
}
}
return cancel;
}
/// <summary>
/// 文件下载完毕执行的操作
/// </summary>
void DownloadCompleted(object sender, DownloadCompleteEventArgs e)
{
mList.Add(e.Manifest);
if (mList.Count == mLen)
{
updater.Activate(mList.ToArray());
mList.Clear();
}
}
void DownloadError(object sender, DownloadErrorEventArgs e)
{
Log.Write("下载过程中出现错误,错误描述:" + e.Error.Message + System.Environment.NewLine + "Version:" + e.Manifest.Version);
XtraMessageBox.Show("下载出错:" + e.Error.Message, "系统提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
void DownloadProgressChanged(object sender, DownloadProgressEventArgs e)
{
progressBarControl1.Position = e.ProgressPercentage;
lab_percent.Text = e.ProgressPercentage.ToString() + "%";
lab_percent.Update();
lab_fileinfo.Text = string.Format("字节数:{0}/{1}", e.BytesReceived, e.TotalBytesToReceive);
lab_fileinfo.Update();
lab_filename.Text = "正在下载文件:" + e.FileName;
lab_filename.Update();
}
private void InitUpdater()
{
//从配置文件动态设置更新标题
UpdaterConfigurationView updateCfgView = new UpdaterConfigurationView();
var manifests = updater.CheckForUpdates();
mLen = manifests.Length;
if (updater.HasNewVersion)
{
//显示本次更新内容
string updateDescription = manifests[0].Description;
this.lblUpdateLog.Text = string.Format("更新说明:{0}", updateDescription);
if (args != null && args.Length > 0)
{
#region 关闭主程序
try
{
string entryPoint = manifests[0].MyApplication.EntryPoint.File;
KillProcessDos(entryPoint);
}
catch (Exception ex)
{
Log.Write(ex.ToString());
}
#endregion
}
isComplete = false;
updater.DownloadAsync(manifests);
}
else
{
lab_filename.Text = "";
XtraMessageBox.Show("您当前的版本已经是最新,不需要更新。", "系统提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
Exit();
}
}
/// <summary>
/// 使用DOS关闭进程
/// </summary>
/// <param name="processName">进程名称</param>
private void KillProcessDos(string processName)
{
RunCmd("taskkill /im " + processName + " /f ");
}
/// <summary>
/// 系统退出
/// </summary>
private void Exit()
{
this.Close();
Environment.Exit(0);
}
/// <summary>
/// 带参数启动指定的应用程序
/// </summary>
/// <param name="entryPoint">入口的应用程序</param>
/// <param name="parameters">程序启动参数</param>
private void Startup(string entryPoint, string parameters)
{
try
{
// if (args != null && args.Length > 0)
{
// if (args[0] == OPEN_FLAG)
{
//关闭主程序
ExeCommand("taskkill /im " + Path.GetFileName(entryPoint) + " /f ");
//启动主程序
System.Threading.Thread.Sleep(1000);
System.Diagnostics.Process.Start(entryPoint, parameters);
}
}
}
catch (Exception ex)
{
Log.Write(ex);
}
}
/// <summary>
/// DOS命令运行函数
/// </summary>
/// <param name="commandText"></param>
private void ExeCommand(string commandText)
{
Process p = new Process();
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.CreateNoWindow = true;
try
{
p.Start();
p.StandardInput.WriteLine(commandText);
p.StandardInput.WriteLine("exit");
//p.StandardOutput.ReadToEnd();
}
catch
{
}
}
/// <summary>
/// 运行DOS命令
/// DOS关闭进程命令(ntsd -c q -p PID )PID为进程的ID
/// </summary>
/// <param name="command"></param>
/// <returns></returns>
private void RunCmd(string command)
{
//實例一個Process類啟動一個獨立進程
System.Diagnostics.Process p = new System.Diagnostics.Process();
//Process類有一個StartInfo屬性這個是ProcessStartInfo類包括了一些屬性和方法下面我們用到了他的幾個屬性
p.StartInfo.FileName = "cmd.exe"; //設定程序名
p.StartInfo.Arguments = "/c " + command; //設定程式執行參數
p.StartInfo.UseShellExecute = false; //關閉Shell的使用
p.StartInfo.RedirectStandardInput = true; //重定向標準輸入
p.StartInfo.RedirectStandardOutput = true; //重定向標準輸出
p.StartInfo.RedirectStandardError = true; //重定向錯誤輸出
p.StartInfo.CreateNoWindow = true; //設置不顯示窗口
p.Start(); //啟動
//p.StandardInput.WriteLine(command); //也可以用這種方式輸入要執行的命令
//p.StandardInput.WriteLine("exit"); //不過要記得加上Exit要不然下一行程式執行的時候會當機
p.StandardOutput.ReadToEnd(); //從輸出流取得命令執行結果
while (!p.HasExited)
{
p.WaitForExit(1000);
}
}
}
}