C#做的在线升级小程序

简介:

转自原文C#做的在线升级小程序

 

  日前收到一个小任务,要做一个通用的在线升级程序。更新的内容包括一些dll或exe或、配置文件。升级的大致流程是这样的,从服务器获取一个更新的配置文件,经过核对后如有新的更新,则会从服务器下载相应的文件更新到被升级的程序目录下。如果被升级的程序在升级之前已经启动,程序则会强制关闭它,待到升级完成之后重新启动相应的程序。在升级之前程序会自动备份一次,以防升级失败造成程序不能运行。

 

首先来的是数据实体

复制代码
    public class FileENT
    {
        public string FileFullName { get; set; }

        public string Src { get; set; }

        public string Version { get; set; }

        public int Size { get; set; }

        public UpdateOption Option { get; set; }
    }
复制代码

 

下面这个类时程序的一些参数,包括了系统的配置参数,为了程序能通用一点,就加了配置上去。

  AppParameter

 

接着就介绍程序的代码

程序是用窗体来实现的,下面三个是窗体新添加的三个字段

        private bool isDelete = true;    //是否要删除升级配置
        private bool runningLock = false;//是否正在升级
        private Thread thread;           //升级的线程

载入窗体时需要检查更新,如果没有更新就提示”暂时无更新”;如果有更新的则先进行备份,备份失败的话提示错误退出更新。

复制代码
            if (CheckUpdate())
            {
                if (!Backup())
                {
                    MessageBox.Show("备份失败!");
                    btnStart.Enabled = false;
                    isDelete = true;
                    return;
                }

            }
            else
            {
                MessageBox.Show("暂时无更新");
                this.btnFinish.Enabled = true;
                this.btnStart.Enabled = false;
                isDelete = false;
                this.Close();
            }
复制代码

 

在这些操作之前还要检测被更新程序有否启动,有则将其关闭。

复制代码
            List<string> processNames = new List<string>();
            string mainPro = string.Empty;
            processNames.AddRange(AppParameter.AppNames);
            for (int i = 0; i < processNames.Count; i++)
            {
                processNames[i] = processNames[i].Substring(processNames[i].LastIndexOf('\\')).Trim('\\').Replace(".exe", "");
            }
            mainPro = processNames.FirstOrDefault();
            AppParameter.IsRunning = ProcessHelper.IsRunningProcess(mainPro);
            if (AppParameter.IsRunning)
            {
                MessageBox.Show("此操作需要关闭要更新的程序,请保存相关数据按确定继续", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                foreach (string item in processNames)
                    ProcessHelper.CloseProcess(item);
            }
复制代码

 

另外上面用到的CheckUpdate( )和Backup( )方法如下

  View Code

 

下面则是更新部分的代码,使用了多线程。出于两方面的考虑,一是进度条需要;二是如果用单线程,万一更新文件下载时间过长或者更新内容过多,界面会卡死。

复制代码
/// <summary>
/// 更新
/// </summary>
public void UpdateApp()
{
    int successCount = 0;
    int failCount = 0;
    int itemIndex = 0;
    List<FileENT> list = ConfigHelper.GetUpdateList();
    if (list.Count == 0)
    {
        MessageBox.Show("版本已是最新", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
        this.btnFinish.Enabled = true;
        this.btnStart.Enabled = false;
        isDelete = false;
        this.Close();
        return;
    }
    thread = new Thread(new ThreadStart(delegate
    {
        #region thread method

        FileENT ent = null;

        while (true)
        {
            lock (this)
            {
                if (itemIndex >= list.Count)
                    break;
                ent = list[itemIndex];


                string msg = string.Empty;
                if (ExecUpdateItem(ent))
                {
                    msg = ent.FileFullName + "更新成功";
                    successCount++;
                }
                else
                {
                    msg = ent.FileFullName + "更新失败";
                    failCount++;
                }

                if (this.InvokeRequired)
                {
                    this.Invoke((Action)delegate()
                    {
                        listBox1.Items.Add(msg);
                        int val = (int)Math.Ceiling(1f / list.Count * 100);
                        progressBar1.Value = progressBar1.Value + val > 100 ? 100 : progressBar1.Value + val;
                    });
                }


                itemIndex++;
                if (successCount + failCount == list.Count && this.InvokeRequired)
                {
                    string finishMessage = string.Empty;
                    if (this.InvokeRequired)
                    {
                        this.Invoke((Action)delegate()
                        {
                            btnFinish.Enabled = true;
                        });
                    }
                    isDelete = failCount != 0;
                    if (!isDelete)
                    {
                        AppParameter.Version = list.Last().Version;
                        ConfigHelper.UpdateAppConfig("version", AppParameter.Version);
                        finishMessage = "升级完成,程序已成功升级到" + AppParameter.Version;
                    }
                    else
                        finishMessage = "升级完成,但不成功";
                    MessageBox.Show(finishMessage, "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    runningLock = false;
                }
            }
        }
        #endregion
    }));
    runningLock = true;
    thread.Start();
}

/// <summary>
/// 执行单个更新
/// </summary>
/// <param name="ent"></param>
/// <returns></returns>
public bool ExecUpdateItem(FileENT ent)
{
    bool result = true;

    try
    {

        if (ent.Option == UpdateOption.del)
            File.Delete(ent.FileFullName);
        else
            HttpHelper.DownLoadFile(ent.Src, Path.Combine(AppParameter.MainPath, ent.FileFullName));
    }
    catch { result = false; }
    return result;
}
复制代码

 

只开了一个子线程,原本是开了5个子线程的,但是考虑到多线程会导致下载文件的顺序不确定,还是用回单线程会比较安全。线程是用了窗体实例里的thread字段,在开启线程时还用到runningLock标识字段,表示当前正在更新。当正在更新程序时关闭窗口,则要提问用户是否结束更新,若用户选择了是则要结束那个更新进程thread了,下面则是窗口关闭的时间FormClosing事件的方法。

 1             if (runningLock )
 2             {
 3                 if (MessageBox.Show("升级还在进行中,中断升级会导致程序不可用,是否中断",
 4                           "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Asterisk) == DialogResult.Yes)
 5                 {
 6                     if (thread != null) thread.Abort();
 7                     isDelete = true;
 8                     AppParameter.IsRunning = false;
 9                 }
10                 else 
11                 {
12                     e.Cancel = true;
13                     return;
14                 }
15             }
16             if (isDelete) File.Delete(AppParameter.LocalUPdateConfig);

在这里还要做另一件事,就是把之前关了的程序重新启动

1             try
2             {
3                 if (AppParameter.IsRunning) ProcessHelper.StartProcess(AppParameter.AppNames.First());
4             }
5             catch (Exception ex)
6             {
7 
8                 MessageBox.Show("程序无法启动!" + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
9             }

在这里展示一下更新的界面。挺丑的,别笑哈。

更新程序的配置信息如下

1   <appSettings>
2     <add key="backupPath" value="C:\Users\Administrator\Desktop\temp\backup"/>
3     <add key="serverURL" value="http://localhost:8015/updateconfig.xml"/>
4     <add key="localUPdateConfig" value="E:\HopeGi\Code\MyUpdate\MyUpdate\bin\Debug\updateconfig.xml"/>
5     <add key="version" value="2"/>
6     <add key="mainPath" value="C:\Users\Administrator\Desktop\temp\main"/>
7     <add key="appName" value="D:\test.exe"/>
8   </appSettings>

完整文档下载:http://pan.baidu.com/share/link?shareid=443378&uk=85241834


没有整理与归纳的知识,一文不值!高度概括与梳理的知识,才是自己真正的知识与技能。 永远不要让自己的自由、好奇、充满创造力的想法被现实的框架所束缚,让创造力自由成长吧! 多花时间,关心他(她)人,正如别人所关心你的。理想的腾飞与实现,没有别人的支持与帮助,是万万不能的。



    本文转自wenglabs博客园博客,原文链接:http://www.cnblogs.com/arxive/p/6372710.html ,如需转载请自行联系原作者





相关文章
|
4月前
|
Web App开发 移动开发 小程序
"项目中mpaas升级到10.2.3 适配Android 14之后 app中的H5以及小程序都访问不了,
"项目中mpaas升级到10.2.3 适配Android 14之后 app中的H5以及小程序都访问不了,显示“网络不给力,请稍后再试”,预发内网版本不能使用,线上版本可以正常使用,这个是什么原因啊,是某些参数没有配置吗,还是说是一些参数改错了?
56 2
|
25天前
|
开发框架 小程序 .NET
C#动态生成带参数的小程序二维码
C#动态生成带参数的小程序二维码
|
1月前
|
存储 缓存 小程序
『Linux升级路』进度条小程序
『Linux升级路』进度条小程序
|
2月前
|
小程序 IDE API
【社区每周】订单中心支持沙箱调试;小程序开发管理文档结构升级(11月第四期)
【社区每周】订单中心支持沙箱调试;小程序开发管理文档结构升级(11月第四期)
19 0
|
2月前
|
移动开发 小程序 Go
【社区每周】小程序消息订阅插件升级为消息订阅接口(2022年8月第五期)
【社区每周】小程序消息订阅插件升级为消息订阅接口(2022年8月第五期)
19 0
|
2月前
|
小程序 安全 搜索推荐
【社区每周】代创建小程序接口支持同步升级商家账号;提审接口上线审核驳回截图功能(2022年7月第四期)
【社区每周】代创建小程序接口支持同步升级商家账号;提审接口上线审核驳回截图功能(2022年7月第四期)
82 0
|
2月前
|
移动开发 运维 小程序
支付宝开放平台小程序控制台全新升级
支付宝开放平台小程序控制台全新升级
72 0
|
2月前
|
运维 小程序 API
社区每周丨支付宝小程序导航栏升级及人脸认证计费规则更新
社区每周丨支付宝小程序导航栏升级及人脸认证计费规则更新
36 0
|
2月前
|
小程序 IDE Go
社区每周丨小程序企业经营类目升级及IDE新版本上线(4月第1周)
社区每周丨小程序企业经营类目升级及IDE新版本上线(4月第1周)
24 0
|
3月前
|
监控 小程序 前端开发
C#医院预约挂号小程序源码(前端+后台)
线上预约挂号系统构建了医院和患者的连接,通过改善患者院内的就医服务流程,以微信公众号、支付宝小程序为患者服务入口,为居民提供导诊、预约、支付、报告查询等线上线下一体化的就医服务,缩短患者就诊环节,提高医疗机构服务效率。
80 0