.NET实现之(自动更新)

做开发的人,尤其是做客户端(C/S)系统开发的人都会遇到一个头疼的问题,就是软件的自动更新;系统发布后怎样自动的更新程序,在下有幸开发过一个自动更新程序,更新程序与任何宿主程序是完全独立的;只要在主程序里面启动更新程序就行了;更新程序也是一个可执行文件,在启动的时候可以设置是否是自动更新和是否是手动更新,自动更新的意思就是说不需要人工的干预实现从远程服务器下载更新包,而如果是手动更新就会涉及到用户点击程序中的按钮实现更新;在自动更新与手动更新中可以根据项目的需要进行选择,有的程序必须要求用户进行更新才能继续使用,所以程序自动更新是有必要的;手动更新就是用户可以随时更新程序,不需要严格的控制版本问题;下面本人就来讲一下具体的实现细节,我贴出部分代码,源码属公司财产本人不宜上传;

自动更新的目的就是将服务器上的DLL文件拷贝到本地执行目录中,并且覆盖本地同名的文件;流程很简单,但是实现起来有几个地方需要注意:

1.大批量的DLL文件怎么下载到本地来,有多个DLL文件在下载过程中如果网速慢的情况下可能出现丢包、丢文件等情况;本人的实现是将多个文件通过ICSharpCode.SharpZipLib组件进行打包,这样可以省很多事;(如:动态连接库文件dll的名称在传输过程中大小写可能会变化)

2.下载到本地了,怎么覆盖原有的同名文件;本人的实现是先同名的文件的支持删除,然后解压缩;这个过程需要临时保存删除的文件,防止操作失败程序无法启动,要注意有事务性的原理;

3.如果更新的文件不只是单单的DLL文件可能还有一些无限极的文件夹;本人的实现是如果存在同名的文件夹,直接递归的删除,然后将其解压缩到目录中;由于压缩包解压后的顶级目录是压缩文件的名称,所有在复制的过程中需要注意目录的层次关系;

下面我们来走一下实现的整个流程,虽然没有给出整个源码,但是如果看完这篇文章的你基本实现起来没什么大问题了;

为了部署方便我建议大家麻烦点实现一个部署文件的工具,将所有的文件直接打包在里面同时生成服务器端的版本信息文件;

利用这个工具就很方便的实现了对文件进行压缩、生成HASH值、版本文件、更新地址等信息;

这个XML中保存的是服务当前的版本信息、更新文件的名称、更新文件的HASH值,为什么需要HASH就是怕更新文件在某些情况下被人调包了,如果所有的客户端更新后后果很严重;所以我们必须带上HASH值;

工具生成两个文件,一个是版本文件一个是更新包,服务器的任务已经完成,下面就是具体的客户端的实现;

为了知道何时需要进行版本更新所以要在客户端程序目录中保存一份用来记录版本信息的文件;

文件中保存着当前本地的版本号、服务器的更新地址、宿主程序的名称,需要宿主的名称就能在更新的时候将宿主程序重进程中枚举出来然后关掉,这样就不影响我们更新了,当然也可以实现宿主程序不关闭的情况下更新,如果用到某些已经被宿主程序占用的情况会直接影响更新流程,所以以防万一关了为妙;

这是客户端版本文件中保存的信息;

我们上面说了,更新分为手动和自动,我们先来说手动更新吧,手动更新就是需要用户自己去点击更新按钮然后开始更新,这个问题我们可以利用进程的参数传递解决;

当然在更新程序里面需要有这方面的逻辑判断;

入口的地方我们进行判断,更新方式;这里的下载远程更新包是用WebClient对象,也可以用其他的基于Socket的对象;更新开始之前需要先判断本地的版本号是否小于远程版本号,如果小于在进行更新;

因为下载的过程是异步的所以需要用到后台线程建议大家使用System.ComponentModel.BackgroundWorker这个后台线程对象,他对Thread进行了很好的封装;下面来看一下核心的流程代码:

//开始辅助线程操作
        private void Back_thread_DoWork(object sender, DoWorkEventArgs e)
        {
            try
            {
                //实例化下载对象
                downclient = new WebClient();
                downclient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(downclient_DownloadProgressChanged);
                downclient.DownloadFileCompleted += new AsyncCompletedEventHandler(downclient_DownloadFileCompleted);
                //下载远程更新包down.zip压缩文件|放在应用程序目录下|相应界面事件
                downclient.DownloadFileAsync(new Uri(Util.GetUpdateUrl() + "down.zip"), Util.GetDictiory() + "\\down.zip");
            }
            catch (Exception err) { System.Diagnostics.Debug.WriteLine(err); }
        }
        //在异步下载结束时触发该事件
        void downclient_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
        {
            try
            {

                if (e.Error != null)
                {
                    eventLog1.WriteEntry(e.Error.ToString());
                    MessageBox.Show("在进行远程更新时,发生错误", "信息提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    Util.KillProcess();//关闭主进程
                    //验证哈希值
                    if (Util.IsHash(Util.GetHash(Util.GetDictiory() + "\\down.zip"), FileWork.GetDownHash()))
                    {
                        //删除无用压缩文件
                        File.Delete(Util.GetDictiory() + "\\down.zip");
                        //删除无用版本文件
                        File.Delete(Util.GetDictiory() + "\\ServerUpdateFiles.xml");
                        MessageBox.Show("远程服务器更新包已发生变化,无法更新", "信息提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        eventLog1.WriteEntry("远程服务器中的更新包在制作和下载时间段中数据包发生变化,为了安全期间不给予下载!");
                        this.Close();
                    }
                    else
                    {
                        //解压压缩包文件
                        ReduceToUnReduceFile.unZipFile(Util.GetDictiory() + "\\down.zip", Util.GetDictiory());
                        //删除压缩包文件
                        File.Delete(Util.GetDictiory() + "\\down.zip");
                        //检查文件夹层次结构
                        FileWork.LookFiles(Util.GetDictiory() + "\\down", Util.GetDictiory());
                        //订阅复制文件事件
                        FileWork.CopyFileEvent += new FileWork.CopyFileDelegate(FileWork_CopyFileEvent);
                        //递归复制文件
                        FileWork.CopyFiles(Util.GetDictiory() + "\\down", Util.GetDictiory());
                        //删除临时文件夹
                        FileWork.DeleteFiles(Util.GetDictiory() + "\\down");
                        //如果库结构更新成功,则才能更新程序的版本号,否则下次继续更新
                        if (EventChainReference.GlobalEventChain.OnAutoUpdateDb())
                            //更新本地版本号信息
                            Util.UpdateLocalXml();
                        File.Delete(Util.GetDictiory() + "\\ServerUpdateFiles.xml");

                        MessageBox.Show("升级成功!", "信息提示");
                        Util.StartProcess();
                        isupdate = true;

                    }
                }
            }
            catch (Exception err) { eventLog1.WriteEntry(err.ToString()); }
            Application.Exit();
        }

这部分代码是串联整个过程的代码;

自动更新大概就讲完了,几个关键的地方都给出了,希望对大家开发自动更新程序有帮助;

时间: 2024-08-31 20:25:01

.NET实现之(自动更新)的相关文章

PHP实现网页自动更新块

  前言:现在很多有个人主页或者博客的朋友选择租用虚拟主机,而相当一部分虚拟主机支持PHP.如果你有一个支持php的主机空间,有没有用php把自己的网站武装起来呢? 能不能让php为你的网页添加一些每隔一段时间就自动更新的内容,以更好的吸引访客呢?实现这一功能并不需要太高深的编程知识,请看以下例子: (一)英语谚语 让我们来看一个简单的应用:让php程序从数据库中随机提取一行记录,显示在网页上,隔15分钟再去读取另一条记录.英汉对照的谚语是个适合显示的内容. 考虑到放置个人主页的廉价虚拟主机多数

微软提供自动更新拦截工具的官方下载

[科技讯]2月1日消息,近日微软在其官方网站上提供了IE10的自动更新拦截工具IE10 Blocker Toolkit的下载,这无疑是宣示着微软IE10 for Win7的即将发布.     据了解,为了防止给那些不愿升级新版的用户造成烦扰,微软通常会在Windows SP或是IE新版推送之前发布拦截工具,这样,用户即使开启着自动更新,也不会被迫升级.现在微软发布了IE10 Blocker Toolkit,那么按照惯例,在未来的数周时间里,微软就会发布IE10 for Win7正式版了.    

Windows 7自动更新开启/升级包卸载方法

  本文介绍Windows 7自动更新开启及Windows 7自动升级包的卸载方法,同样适用于Vista,如果想卸载Windows XP升级补丁包,请参考文末的步骤及注意事项,平时遇到不小心安装的补丁程序,可以通过本文的方法卸载掉,另外由于卸载升级包需要考虑到先后次序问题,所以,应该尽可能的优先考虑Windows 7系统保护功能,只要开启保护,Windows 7会自动创建还原点,系统还原比手动卸载更有效. 一.开启Windows 7自动更新 使用Windows 7的用户建议全部开启自动更新,天缘

怎么关闭Win7系统自动更新

  怎么关闭Win7系统自动更新 1.在任意位置新建一个文本文档; 2.打开新建的文本文档,将下面这段代码复制进去: @echo off disable the win7 auto running netsh interface tcp set global rss=disabled netsh interface tcp set global autorunning level=disabled 2.点击左上角的"文件"-"另存为",在保存界面首先选择好文件保存位

maven 多 web 工程 怎么自动合并到 一个 主web 工程 且修改文件 自动更新修改

问题描述 maven 多 web 工程 怎么自动合并到 一个 主web 工程 且修改文件 自动更新修改 如题所属: maven 多 web 工程 怎么自动合并到 一个 主web 工程 且修改文件 自动更新修改,等于在一个web project 部署多个web 开发

怎么关闭win7自动更新结束重启提示

windows 7系统是时下最主流的操作系统,但不少朋友可能会遇到这样的情况,系统经常会定期自动联网更新,自动更新完成提示您电脑需要重新以便完成操作,但很多用户由于手头工作没有完成,看到有消息框弹出来,经常选到了重新启动电脑,导致还没完成的电脑数据丢失.其实这里的祸根是系统自动更新,然后自动更新完成后,弹出需要重新启动电脑,完成系统更新操作,但现实是我们并不需要系统自动更新,并且很反感弹出重启对话框. 那么如何解决windows 7自动更新,并且弹出重启对话框呢?解决办法主要有2个,一个是关闭电

Win8系统如何关闭自动更新?

  Win8系统如何关闭自动更新?          步骤一:关闭系统自动更新 1.右击桌面上的"计算机",选择"属性". 2.单击最左下角的"Windows更新"链接. 3.再单击"Windows更新"窗口左侧的"更改设置"链接. 4.选择下拉菜单下的"从不检查更新(不推荐)". 5.接着取消下面的两个复选框,在弹出的对话框中单击"确定"按钮. 6.最后再单击&qu

asp.net自动更新组件分享

一. 摘要 前两天在博客上发布了一篇英文的自动更新组件文章Release a AutoUpdater tool,那么在这篇文章中,我们也对其功能进行一些简单说明,这个组件非常简单,所以大家可以下载进行一些改进.众所周知,对于一般的软件开发,在开始的时候都会有一个技术选型的阶段,最大的选型就是首先要确定是选择Client/Server模式还是Browser/Server模式.综合而论:两者各有优劣,在很多方面都不能被对方互相取代,如在适用Internet.维护工作量等方面,B/S比C/S要强很多:

实现.NET应用程序的自动更新

程序 应用程序更新的方法一般有两种:一是通知用户(比如发E-mail),让用户到指定的网站地址下载更新的程序:二是将更新的职责从用户那边转移到应用程序自身,由应用程序自身取代用户获取并安装一个软件的更新,客户端应用程序自身负责从一个已知服务器下载并安装更新,用户唯一需要进行干预的是决定是否愿意现在或以后安装新的更新.显然,后者比前者更友好.你现在可以看到类似后一种方法的实际产品,比如Windows XP和Microsoft Money.本文所介绍的.NET应用程序更新组件就可以提供类似的功能.

一个无刷新效果定时自动更新页面的例子

定时|刷新|无刷新|页面 一个无刷新效果定时自动更新页面的例子(ASP.NET2.0-应用xmlhttp) 首先在ASP.Net创建两个WebForm页,分别命名为Default1,Default2.下面给出代码清单: //Default1.aspx <%@ Page Language="C#" Debug="true" AutoEventWireup="true" CodeFile="Default1.aspx.cs"