前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C# WinForm实现自动更新程序的案例分享

C# WinForm实现自动更新程序的案例分享

原创
作者头像
用户7718188
发布2022-11-06 20:14:33
7570
发布2022-11-06 20:14:33
举报
文章被收录于专栏:高级工程司高级工程司

实现代码

/// <summary>

/// 更新自己

/// </summary>

private void CopyRun() {

string runPath = Process.GetCurrentProcess().MainModule.FileName;

string runName = Path.GetFileName(runPath);

if(!runName.StartsWith("_")) {

string copyPath = runPath.Replace(runName, "_" + runName);

byte[] bytes;

using(FileStream fileStream = new FileStream(runPath, FileMode.Open, FileAccess.Read)) {

bytes = new byte[fileStream.Length];

fileStream.Read(bytes, 0, bytes.Length);

}

using(FileStream fileStream = new FileStream(copyPath, FileMode.Create, FileAccess.Write)) {

fileStream.Write(bytes);

}

ProcessStartInfo info = new ProcessStartInfo(copyPath, _runApp);

Process.Start(info);

Environment.Exit(0);

}

}

/// <summary>

/// 更新UI

/// </summary>

/// <param name="actoin"></param>

private void UpdateUI(Action actoin) {

if(this.InvokeRequired) {

this.BeginInvoke(actoin);

}

else {

actoin();

}

}

/// <summary>

/// 获取本地更新地址

/// </summary>

/// <returns></returns>

private string GetUpdateUrl() {

XElement xele = XElement.Load(updateXml);

string url = xele.Element("url").Value;

return url;

}

/// <summary>

/// 获取本地更新文件

/// </summary>

/// <returns></returns>

private string GetUpdateFiles() {

XDocument xdoc = XDocument.Load(updateXml);

var files = from f in xdoc.Root.Element("files").Elements() select new { name = f.Attribute("name").Value, version = f.Attribute("version").Value };

return JsonConvert.SerializeObject(files);

}

/// <summary>

/// 更新完成后修改版本文件

/// </summary>

/// <param name="list"></param>

private void UpdateXml(List<UpdateModel> list) {

XDocument xdoc = XDocument.Load(updateXml);

foreach(var model in list) {

var ele_files = xdoc.Root.Element("files");

XElement xele = ele_files.Elements().FirstOrDefault(s => s.Attribute("name").Value == model.name);

if(xele != null) {

xele.SetAttributeValue("version", model.version);

}

else {

XElement addXele = new XElement("file");

addXele.SetAttributeValue("name", model.name);

addXele.SetAttributeValue("version", model.version);

ele_files.Add(addXele);

}

}

xdoc.Save(updateXml);

}

readonly string _runApp;

public Form_update(string runApp) {

InitializeComponent();

_runApp = runApp;

//CopyRun();

}

readonly string updateXml = Application.StartupPath + "UpdateList.xml";

private void btn_update_Click(object sender, EventArgs e) {

#region 设置ui

btn_update.Enabled = false;

label_status.Text = "正在更新";

#endregion

#region 初始化路径

string savePath = Application.StartupPath + "temp_update\\";

string backPath = Application.StartupPath + "temp_back\\";

if(Directory.Exists(savePath)) {

Directory.Delete(savePath, true);

}

Directory.CreateDirectory(savePath);

if(Directory.Exists(backPath)) {

Directory.Delete(backPath, true);

}

Directory.CreateDirectory(backPath);

#endregion

#region 图标旋转

int angle = 0;

Image img = pictureBox1.BackgroundImage;

System.Threading.Timer timer = new System.Threading.Timer(s => {

UpdateUI(() => {

angle = angle == 360 ? 0 : angle + 10;

pictureBox1.BackgroundImage = img.RotateImage(angle);

});

}, null, 0, 100);

#endregion

#region 下载更新

string url = GetUpdateUrl();

bool isSuccess = false;

Task.Run(() => {

try {

//获取下载列表

HttpResult httpResult = HttpUtil.HttpRequest(new HttpItem(url + "GetUpdateFiles", requestData: GetUpdateFiles()));

if(httpResult.Status) {

UpdateModel_Out output = JsonConvert.DeserializeObject<UpdateModel_Out>(httpResult.HttpStringData);

if(output.updateList.Count == 0) {

throw new Exception("当前已是最新版本");

}

UpdateUI(() => {

progressBar1.Maximum = output.updateList.Count + 1;

});

//循环下载文件

for(int i = 0; i < output.updateList.Count; i++) {

UpdateModel updateModel = output.updateList[i];

#region 进度条

UpdateUI(() => {

label_status.Text = $"正在更新第 {i + 1}/{output.updateList.Count} 个文件,文件名:{updateModel.name}";

progressBar1.Value = i + 1;

});

#endregion

#region 下载文件

httpResult = HttpUtil.HttpRequest(new HttpItem(url + "DownloadFile", requestData: JsonConvert.SerializeObject(updateModel)));

if(httpResult.Status) {

using(FileStream fileStream = new FileStream(savePath + updateModel.name, FileMode.Create)) {

fileStream.Write(httpResult.HttpByteData, 0, httpResult.HttpByteData.Length);

}

}

else {

throw new Exception(updateModel.name + "下载失败,请重试");

}

#endregion

Task.Delay(1000).Wait();

}

#region 备份

UpdateUI(() => {

label_status.Text = "正在备份";

});

try {

File.Copy(updateXml, backPath + "UpdateList.xml");

foreach(var file in output.updateList) {

if(File.Exists(Application.StartupPath + file.name)) {

File.Copy(Application.StartupPath + file.name, backPath + file.name, true);

}

}

}

catch { }

#endregion

#region 完成更新

UpdateUI(() => {

label_status.Text = "正在完成更新";

progressBar1.Value = progressBar1.Maximum;

});

string[] files = Directory.GetFiles(savePath);

try {

#region 更新成功

foreach(string file in files) {

File.Copy(file, Application.StartupPath + Path.GetFileName(file), true);

}

Directory.Delete(savePath, true);

#region 保存最新版本

UpdateXml(output.updateList);

isSuccess = true;

UpdateUI(() => {

label_status.Text = "更新完成";

});

#endregion

#endregion

}

catch {

#region 失败回滚

UpdateUI(() => {

label_status.Text = "更新失败,正在回滚";

});

string[] files_back = Directory.GetFiles(backPath);

foreach(string file in files_back) {

File.Copy(file, Application.StartupPath + Path.GetFileName(file), true);

}

File.Copy(backPath + "UpdateList.xml", updateXml, true);

UpdateUI(() => {

label_status.Text = "回滚完成";

});

return;

#endregion

}

#endregion

}

else {

throw new Exception("获取更新列表失败");

}

}

catch(Exception ex) {

UpdateUI(() => {

label_status.Text = "更新失败!" + ex.Message;

btn_update.Enabled = true;

});

}

finally {

UpdateUI(() => {

timer.Change(-1, -1);

pictureBox1.BackgroundImage = img;

if(isSuccess) {

if(File.Exists(_runApp)) {

if(MessageBox.Show("更新完成,是否打开程序", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) {

Process.Start(_runApp);

}

Environment.Exit(0);

}

}

});

}

});

#endregion

}

private void btn_close_Click(object sender, EventArgs e) {

Close();

}

private void panel1_Paint(object sender, PaintEventArgs e) {

Pen pen = new Pen(Color.LightGray);

e.Graphics.DrawLine(pen, new Point(36, 36), new Point(panel1.Width - 36, 36));

}

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 实现代码
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档