欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

ClickOnce DIY全自动更新下载升级的自我实现

程序员文章站 2022-05-31 12:46:07
smartclient概念近来比较热,但在微软提出这个名词以前已经有大量的软件在这么做了,一方面是简化客户端的部署,一方面是提供自动升级的功能;对于传统的winform应用...
smartclient概念近来比较热,但在微软提出这个名词以前已经有大量的软件在这么做了,一方面是简化客户端的部署,一方面是提供自动升级的功能;对于传统的winform应用来讲,确实是可以降低维护成本的一个不错的解决方案;
 微软在推出smartclient概念时,推出了相关的updater的application block,做的也蛮不错,但作者前段还是根据软件特性自己写了一个很简单的实现,大家也大概能了解一下原理:
笔者的简化版自动升级管理器只需要四步走:
1.一个负责查找和下载新版本的本地类
2.本地配置文件中(或在代码中硬编码?不太好吧),指向更新服务器的url
3.服务器上一个标识版本号和新文件url的配置文件
4.调用示例
1.版本管理类
using system;
using system.collections.generic;
using system.text;
using system.xml;
using system.net;
using system.io;
using system.windows.forms;
namespace survey
{
    class versionagent
    {
        public static bool checknetwork()
        {
            httpwebrequest request;
            try
            {
                request = (httpwebrequest)webrequest.create(pub.getsetting("updateurl") );//从本地配置文件获取的网络中配置文件的url
                request.proxy = webproxy.getdefaultproxy();
                request.getresponse();//如果可以获得响应,说明网络没问题
            }
            catch (exception e)
            {
                pub.logerror(e);
                return false;
            }
            return true;
        }

        public static bool checkupdate()
        {
            xmldocument doc = loadxmldocument(pub.getsetting("updateurl"));
            sys.updateurl = getvalue(doc, "downloadurl").trim();//将来会用这个url自动下载 
            sys.updatepage = getvalue(doc, "downloadpage").trim();//如自动下载失败,会提供到这个页面手工下载
            string warningrate = getvalue(doc, "warningrate").trim();
            float.tryparse(warningrate,out sys.warningrate);
            string netversion = getvalue(doc, "version").trim();
version localversion=system.reflection.assembly.getexecutingassembly().getname().version;
            return new version(netversion).compareto(new version(localversion))>0;//大于0说明有新版本发布
        }//这个方法是载入网络配置文件,读取一些不想放在本地的配置参数,以及比较本地和网络版本号
        public static bool goupdate()
        {
          return downloadfile(sys.updatefile,sys.updateurl);

        }
        public static string getvalue(xmldocument doc, string key)
        {
            string value;
            try
            {
                xmlelement elem = (xmlelement)doc.selectsinglenode(@"/config/app/" + key);//读取配置文件可自行定义
                value = elem == null ? "" : elem.getattribute("value"); 
            }
            catch
            {
                value = "";
            }
            return value;
        }
        public static xmldocument loadxmldocument(string filenameorurl)
        {
            xmldocument doc = null;
            try
            {
                doc = new xmldocument();
                doc.load( filenameorurl);
            }
            catch (exception e)
            {
                system.windows.forms.messagebox.show(e.message);
                pub.logerror(e);
                doc = null;
            }
            return doc;
        }

        public static bool downloadfile(string filename, string url)
        {
            bool value = false;
            webresponse response = null;
            stream stream = null;
            try
            {
                httpwebrequest request = (httpwebrequest)webrequest.create(url);
                response = request.getresponse();
                stream = response.getresponsestream();
                if (!response.contenttype.tolower().startswith("text/"))
                {
                    value = savebinaryfile(response, filename);
                }
            }
            catch (exception e)
            {
               // system.windows.forms.messagebox.show(e.message);
                pub.logerror(e);
            }
            return value;
        }

        private static bool savebinaryfile(webresponse response, string filename)
        {
            bool value = true;
            byte[] buffer = new byte[1024];
            try
            {
                if (file.exists(filename))
                    file.delete(filename);
                stream outstream = system.io.file.create(filename);
                stream instream = response.getresponsestream();
                int l;
                do
                {
                    l = instream.read(buffer, 0, buffer.length);
                    if (l > 0)
                        outstream.write(buffer, 0, l);
                }
                while (l > 0);
                outstream.close();
                instream.close();
            }
            catch (exception e)
            {
                system.windows.forms.messagebox.show(e.message);
                pub.logerror(e);
                value = false;
            }
            return value;
        }
    }
}
2.本地配置文件可能如:
<configuration>
  <appsettings>
    <add key="updateurl" value="http://www.abc.com/download/release.xml" />
  </appsettings>
</configuration>
3.网络配置文件可能如:
<config>
  <app>
    <version value="1.1.9.2" />
    <releasedate value="2006-12-12" />
    <downloadpage value="http://www.abc.com/download/index.htm" />
    <downloadurl value="http://www.abc.com/download/update.exe" />
   <warningrate value="0.3" />
  </app>
</config>
4.调用示例
在认为合适的时机(比如说应用程序启动时),启动一个后台线程去工作:
            thread thread = new thread(new threadstart(threadmethodupdate));
            thread.start();

        private void threadmethodupdate()
        {

            if (versionagent.checknetwork())//网络状况正常
            {
                if (versionagent.checkupdate())//检查更新并获取网络参数
                {
                    if (versionagent.goupdate())//获取新版本(由于我的软件很小,所以在不提示用户的情况就进行了新版下载,如认为不妥,可通过messagebox提示一下)
                    {
                        messagebox.show("检测到产品的更新版本,即将开始自动更新!", "版本升级", messageboxbuttons.ok, messageboxicon.information);
                        system.diagnostics.process.start(sys.updatefile);
                        system.environment.exit(0);
                    }
                    else
                    {
                        messagebox.show("系统检测到更新版本,但自动下载失败,点击确定进行手动下载", "版本升级", messageboxbuttons.ok, messageboxicon.error);
                        system.diagnostics.process.start(sys.updatepage);
                        system.environment.exit(0);
                    }
                }
            }
            else//也可以什么也不提示
                messagebox.show("无法连接到服务器进行自动升级!\n请检查网络连接 " + pub.getsetting("updateurl"), "网络异常", messageboxbuttons.ok, messageboxicon.warning);
        }