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); 
        } 
您可能感兴趣的文章:
