一个自动更新小工具
这个更新工具是独立运行的,被更新软件要先自行检查版本,如果有新版本就调用这个更新工具,并退出,防止线程占用导致更新失败。
小工具原理:
0,软件更新包需要用rar制作一个成自解压可执行文件,例如 abc.exe
1,调用一个Post接口,获取到更新包下载地址, 例如:http://192.168.1.99/abc.exe
2,下载更新包,并运行,运行后abc.exe会自解压覆盖原来的程序,完成版本升级
有个缺陷:更新工具不能自己更新自己(待优化)
using Newtonsoft.Json;
using NotifyDialogAutoUpdate.Comm;
using System;
using System.ComponentModel;
using System.Data;
using System.Windows.Forms;
namespace NotifyDialogAutoUpdate
{
public partial class Form1 : Form
{
string fileName = string.Empty; //下载的文件名,从Url中解析出来
string newVersionCode = string.Empty;
string url = string.Empty;
public Form1()
{
InitializeComponent();
try
{
lblCurrentVersion.Text = Asset.ReadAllTextFromFile("Version.txt");
}
catch (Exception ex)
{
lblCurrentVersion.Text = "获取当前版本失败!";
lblError.Text = ex.ToString();
}
try
{
//2,从接口获取版本和下载地址
var dt = PostGetDataTable("GetAppVersion", "");
if (null != dt)
{
newVersionCode = dt.Rows[0]["Version"].ToString();
url = dt.Rows[0]["Url"].ToString();
lblVersion.Text = newVersionCode;
lblUrl.Text = url;
}
else
{
lblUrl.Text = "获取更新失败(dt is null)";
}
}
catch (Exception ex)
{
lblVersion.Text = "获取服务器版本失败!";
lblError.Text = ex.ToString();
}
}
private void BtnUpdate_Click(object sender, EventArgs e)
{
//3杀掉进程 4下载 5执行文件
Util.KillProcess(Asset.AppConfig.NeedKillProcess);
Util.KillProcess(Asset.AppConfig.NeedKillProcess1);
Util.KillProcess(Asset.AppConfig.NeedKillProcess2);
Util.KillProcess(Asset.AppConfig.NeedKillProcess3);
Util.KillProcess(Asset.AppConfig.NeedKillProcess4);
if (string.IsNullOrEmpty(url))
{
labUpdateStatus.Text = Asset.AppConfig.ServerIP;
lblError.Text = lblError.Text + "\r\n下载地址错误! 请联系系统管理员!";
return;
}
//获取文件名
int n = url.LastIndexOf("/");
fileName = url.Substring(n + 1, url.Length - n - 1);
//下载
Util.Download(url, fileName);
//下载完成
OnDownloadFileCompleted(null, null);
//Update.ini的修改方式: 把最新的Update.ini包含在更新包里面
}
//下载完成
private void OnDownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
this.labUpdateStatus.Text = "下载完成...";
this.lblError.Text = "开始解压文件:" + fileName;
this.myProgressBar.Value = 75;
//运行下载的自解压文件
Util.RunProcess(fileName, "");
this.myProgressBar.Value = 100;
this.labUpdateStatus.Text = "更新完成!";
this.lblError.Text = "更新完成!";
var currentVersion = Asset.ReadAllTextFromFile("Version.txt");
this.lblError.Text = "更新完成!更新后版本:" + currentVersion;
DialogResult dr;
dr = MessageBox.Show("更新完成!", "更新完成", MessageBoxButtons.OK,
MessageBoxIcon.Information, MessageBoxDefaultButton.Button1);
if (dr == DialogResult.OK)
Close();
}
Timer timer1 = new Timer();
private void MkXkUpdate_Load(object sender, EventArgs e)
{
timer1.Enabled = true;
timer1.Interval = 1000;
timer1.Tick += new System.EventHandler(this.timer1_Tick);
}
private void timer1_Tick(object sender, EventArgs e)
{
timer1.Stop();
BtnUpdate_Click(null, null);
}
//接口基本地址, 例如 http://localhost:832/ServiceNotify/
public static string ServerIP = Asset.AppConfig.ServerIP;
//根据方法名和参数获取到Json并转换为DataTable输出
//参数method 为 http://localhost:832/ServiceNotify/GetDepartmentALL 中的 GetDepartmentALL
//参数param一般为Json字符串,无参数时传空字符串
public static DataTable PostGetDataTable(string method, string param)
{
try
{
//1,POST
var json = HttpTools.Post(ServerIP, "");
string[,] arr = JsonConvert.DeserializeObject<string[,]>(json);
//2,Convert2Table
return Util.Convert2Table(arr);
}
catch (Exception ex)
{
Log.InsertLog("PostGetDataTable", method + param, ex.ToString());
return null;
}
}
}
}