转C#实现之(自动更新)http://www.cnblogs.com/yelanggu/p/9288149.html

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

//开始辅助线程操作

        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();

        }

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

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

原文地址:https://www.cnblogs.com/H1991/p/9988004.html

时间: 2024-08-28 13:10:27

转C#实现之(自动更新)http://www.cnblogs.com/yelanggu/p/9288149.html的相关文章

Linux下搭建SVN服务器及自动更新项目文件到web目录(www)的方法

首先搭建SVN服务器 1,安装SVN服务端 直接用apt-get或yum安装subversion即可(当然也可以自己去官方下载安装) sudo apt-get install subversion 2,创建版本库 svnadmin create /home/myrepos    //这里的文件目录自己随便设置 3,配置svnserve 上述版本库/home/myrepos建立后在文件夹下会生成conf文件夹,进入/home/myrepos/conf下面会有下面3个文件 authz passwd 

svn自动更新服务器最新代码

1.很简单打开dos界面 cd到svn exe目录下,运行 cd C:\Program Files\TortoiseSVN\bin    --svn安装目录(作者使用时TortoiseSVN客户端,其他客户端未测试过)start TortoiseProc.exe /command:update /path:"F:\_xxx_svn\branches\xxxxx" /closeonend:3 update是命令,/path后面是同步路径start TortoiseProc.exe /co

自动更新开奖数据的excel文件,供大家下载

自动更新开奖数据的excel文件,供大家下载 2010-03-14 20:22 228492人阅读打印来源:乐彩网 作者:eren 很多人拥有自制excel电子表格,常要更新最基本的开奖信息.如有多期未更新,则费时更多.乐彩网为大家提供八种彩票的自动更新文件,供下载.您只需点击更新按钮,就能得到最及时全面的开奖信息,省时省力. 2011年10月12日修改说明:已更新全部开奖数据.福彩3Dexcel文件中,因描述更新范围的高度小了,导致更新后,最下面内容会右移.如此文件单独存在,请直接下载.如已将

windows下svn自动更新

配置hooks下post-commit.bat文件,文件内容如下 @echo offSET REPOS=%1SET REV=%2SET DIR=%REPOS%/hooksSET PATH=%PATH%;SET WORKING=E:/EnvirOnment/WWW @网站根目录svn update %WORKING% --username eves_china --password test2015 注意: 1.svn服务器的程序bin目录需要加入path路径. 2.进入计算机服务-->>Vis

自动更新svn的内容到网站

每次编写网站代码,都是手工复制到服务器然后看效果,现在可以通过svn自动更新网站的代码,方法如下: 1.编写批处理 "C:\Program Files\Subversion\bin\svn.exe" export --force --no-auth-cache --quiet svn://xxxxxx [path] --username [username] --password [password] 相关参数说明: 1.C:\Program Files\Subversion\bin\

eclipes创建一个web项目web.xml不能自动更新的原因(web.xml和@WebServlet的作用)

在eclipse中创建一个Web项目的时候,虽然有web.xml生成,但是再添加Servlet类文件的时候总是看不见web.xml的更新,所以异常的郁闷!上网查了查,原来我们在创建Web项目的时候,会弹出一个对话框,“Dynamic web module version”这个选项默认成了3.0,按照老规范,应该是在eclipse的WebContent \ WEB-INF \ 目录下创建web.xml的.而新规范是可以不用web.xml的,如tomcat 7.0就支持新规范,这样相关的servle

CentOS下建立本地YUM源并自动更新

1. 尽管有很多的免费镜像提供yum源服务,但是还是有必要建立自己的yum服务器,主要出于以下几点考虑: l 网络速度:访问互联网可能比较慢 l 节省带宽:如果有大量的服务器,架设自己的yum源可以有效节省互联网带宽 l 联网限制:对于有些内网服务器,不能连接到互联网 l 对于RHEL(Redhat Enterprise Linux),需要购买服务 l 便于发布自己开发的rpm包 2. 找到适合你的站点的yum同步源,主要是CentOS标准软件仓库.epel.以及rpmforge CentOS标

关闭Centos的自动更新

昨天跟老板汇报,提到我们的linux服务器每天自动更新,老板大发雷霆,说生产系统不能够这样,非常不安全,一个师兄也提到他原来在移动的时候,服务器更新也是很谨慎的事情.看来我的思维太技术了,不够全面,所以回来就把自动更新关了. 操作记录如下: [[email protected] alpha]# chkconfig –list yum-updatesd yum-updatesd    0:关闭  1:关闭  2:启用  3:启用  4:启用  5:启用  6:关闭 [[email protecte

性能优化——统计信息——SQLServer自动更新和自动创建统计信息选项 (转载)

原文译自:http://www.mssqltips.com/sqlservertip/2766/sql-server-auto-update-and-auto-create-statistics-options/?utm_source=dailynewsletter&utm_medium=email&utm_content=headline&utm_campaign=2012913 统计信息是如何提高SQLServer查询性能的?统计直方图用作在查询执行计划中查询优化器的选择依据.