青剑夜羽轩...

青剑衣清寒,夜羽眉流觞..

导航

编写WinForm自动更新程序

转来的,感谢sdlfx博主分享 原地址 http://www.cnblogs.com/sdlfx/archive/2010/11/25/1888207.html
    可能有一两年没有更新博客了,并不是由于没时间,或是这段时间没有丝毫的技术心得,只是每次打开博客,却又感觉无从可写。或许是因为没得到锻炼,文笔功夫过
低吧。所以决定从今天起,借写日志锻炼一下。文档啊,希望下次写的时候不会那么痛苦了。
        从《编写WinForm自动更新程序》开始。
       C/S架构的项目,客户端将不可避免的面临自动更新问题,特别是在客户端数量较多时,自动更新显得尤为重要。据我所了解,WinForm程序自动更新有两种方案:
       1、使用ClickOnce发布客户端;
       2、自己编写自动更新程序;
         鉴于“偷懒”的原则,我试验了一下ClickOnce部署,在经过一番周折后终究是成功了,但感觉还是有几个缺点:
             A、发布不方便。发布一次要生成程序清单、部属清单,生成的文件一不小心就完全不能用,又得重来,还有个似乎没什么用的.deploy;
             B、无法指定程序安装目录。没去找过自动定位的安装目录,料想应该是隐藏得挺深的;
             C、更新时无进度展示。这是比较影响用户体验的,若是更新失败,产生的日志连做开发的也未必知道所以然;
       还有个小缺点,在浏览器上启动安装,总觉得有点怪异。。。。
        于是乎,开始鼓捣一个自动更新程序。在设计过程中有几个问题必须做出选择:
        1、使用什么方式访问更新源?可以通过开发文件读取服务来提供更新源,可以使用FTP作为更新源,可以使用文件共享,可以使用WEB共享,等等。在此我选择了
使用FTP作为更新源;
       2、根据什么来判断文件是否需要更新?首先想到的可能是版本号,但除DLL、EXE文件之外,大部分文件是没有版本号的,内容对比?那更不可取了。我使用了文
件的HASH码来比较。每一个文件都可生成一个唯一的HASH码,只要该文件做过任何改动,生成的HASH码都将不一样。
        程序大致思路:提供一个独立的DLL供主程序调用,传入FTP访问凭据,启动更新程序并将主程序关闭,更新程序首先从FTP上下载一个文件清单,该文件清单中列
举出了新版本中所有文件及目录,并保存了各文件的HASH。下载之后依次与本地文件的HASH对比,若发现不同,则下载文件并更新。遍历完成之后,启动主程序并附
加参数通知调用的DLL已完成了更新,防止死循环,最后退出更新程序。下面说几个技术点:
        文件HASH码生成
    public static string GetMD5(Stream stream)
    {
        byte[] buffer;
        using (HashAlgorithm hash = HashAlgorithm.Create())
        {
            buffer = hash.ComputeHash(stream);
            hash.Clear();
        }
        return Convert.ToBase64String(buffer);
    }

       HashAlgorithm类是.NET框架中提供的,在System.Security.Cryptography命名空间下。这里发生了一件我不太理解的事:使用File.IsExist判断文件是否存在

时,若传递的文件名参数前面多加了“\”,返回结果始终为true,不管文件是否真的存在,如File.IsExist(@”\temp\temp.xml”),更离奇的是,居然可以使用这个路径来生成HASH码。

       应用程序间传递参数

       在写控制台程序的时候,自动生成的Main方法中有参数string[] args,这便是传参入口。另外,可以使用Process类启动应用程序,例如:

    Process.Start(Application.StartupPath + "\\Update.exe", arguments);

       其中arguments是一个字符串,传递多个参数时,参数之间使用空格隔开。若单个参数内部有空格,请将该参数使用双引号括起。传递参数时注意“\”有可能会与

紧随其后的字符组成形成转义,若是在Main中获取参数时发现参数个数不对,那就应该检查一下这个了。

       剩下的似乎就没什么说的了,都是些体力活。至于FTP的访问,用了一个以前一个朋友提供的类,本人也未曾研究其细节。展示更新进度时记得使用Form.Invoke来

更新窗体呈现。

       使用这个自动更新程序时,首先使用Release项目来生成项目文件清单,然后将项目文件清单与生成的FileList.xml文件一并放在某个FTP目录下,配置好访问的用户

名、密码后,在主程序中使用下列语句即可实现自动更新:

      FtpInfo ftpInfo = new FtpInfo("10software.gicp.net", "\\test", "ftpclient", "p@ssw0rd", 21);

      lib.Update.Pipe.Update(ftpInfo, UpdateBaseMode.ByFileHash);

       FTP是在Server2008下配置的,配置过程中遇到了些小麻烦,但终究是成功了。下一篇将简单介绍些Server2008下的FTP配置。

       程序源码:Updater.rar

posted on 2011-04-13 15:11  yudragon  阅读(833)  评论(0编辑  收藏  举报