通用系统自动升级程序的简单实现

       
         开发背景:在平时开发C/S系统时,大家都清楚C/S系统的最大弱点就是不利于维护,当客户端程序更新时不得不到每个用户的机子上去部署。虽然微软的Smart Client技术使得传统的C/S系统更加利维护,但公司现在还不打算采用,而Updater Application Block组件的配置和使用相以地麻烦,所以我们选择采用传统的自动更新的程序。
        自动更新的步骤就是客户端检查服务器端的版本号是否比本地的高,如果高于本地版本,就向服务器请求下载文件。在这里我们服务器端部署的升级文件是任何人都可以下载的。可能与某些情况不同。从上面的描述可以看出,其实所有系统自动升级的步骤都是类似的,所以做一个通用的自动升级程序就一劳逸了。
 
解决方案如下图:
        


类图如下:

        

先让我们来看下升级文件的配置:

服务器端(SystemUpdateXMLFile.xml)

<?xml version="1.0" encoding="utf-8" ?> 
<UpdateConfig>
 
<SystemName Name="Archives" Description="档案系统">
  
<Version>2.0</Version><!--当前版本号码-->
  
<NewFilePath>UpDateFile/Archives</NewFilePath><!--更新文件所在路径-->
  
<Level>1</Level><!--更新等级 1表示强制更新-->
 
</SystemName>

 
<SystemName Name="FinishArchives" Description="成品档案系统">
  
<Version>2.0</Version><!--当前版本号码-->
  
<NewFilePath>UpDateFile</NewFilePath><!--文件所在路径-->
  
<Level>1</Level><!--更新等级 1表示强制更新-->
 
</SystemName>
</UpdateConfig>


客户端:(SystemUpdateXMLFile.xml)

<?xml version="1.0" encoding="utf-8" ?> 
<UpdateConfig>
 
<SystemName Name="FinishArchives" Description="成品档案系统">
  
<Version>1.0</Version><!--当前版本号码-->
  
<AutoUpdate>true</AutoUpdate><!--更新等级 1表示强制更新-->
  
<MainAppPath>MainFrom.exe</MainAppPath><!--主程序路径-->
 
</SystemName>
</UpdateConfig>

App.Config

<configuration>
 
<configSections> 
     
<section name="AutoUpdateIco" type="AutoUpdate.IcoFactory.CustomSectionHandler, AutoUpdate.IcoFactory"/>
 
</configSections>
 
<appSettings>
        
<add key="UpdateWebService" value="http://localhost/AutoUpdate.WebService/VersionInfoService.asmx"></add>
 
</appSettings>
 
<AutoUpdateIco>
         
<add key="ClientAssembly" value="AutoUpdate.ClientComponent.dll" /><!--实现客户端服务的程序集名称-->
         
<add key="ClientComponent" value="AutoUpdate.ClientComponent.XmlFileComponent" /><!--实现客户端服务的类名-->
  
</AutoUpdateIco>        
</configuration>



不难看出每一个系统都需要在服务器端的XML文件中配置类似的信息,也许你觉得XML文件储蓄信息不太好,想把系统的信息放到数据库里,是不是我们的程序就要重写呢?不是的,在设计这个系统时我釆用了依赖注入的方法 由CreateComponentFactory类负责装配相应的服务,  CreateComponentFactory类的部份代码如下:

 #region 得到客户端组件
  
/// <summary>
  
/// 得到客户端组件
  
/// </summary>
  
/// <param name="path"></param>
  
/// <returns></returns>
  public static IClientVersionInfo CreateClientObject(string path)
  {
   
object objType = new object();
   
string assemblyPath = string.Empty;
   
string serverComponent = string.Empty;
   
   GetClientIcoConfig(
out assemblyPath,out serverComponent);
   
   assemblyPath 
= path + "\\" + assemblyPath;
   
try
   {
    objType 
= Assembly.LoadFile(assemblyPath).CreateInstance(serverComponent,false);//反射创建
   }
   
catch(System.Exception e)
   {
    
throw e;
   }
   
return (IClientVersionInfo) objType;
  }
  
#endregion
  
  
#region 得到服务器端组件
  
/// <summary>
  
/// 得到服务器端组件
  
/// </summary>
  
/// <param name="path"></param>
  
/// <returns></returns>
  public static IServerVersionInfo CreateServerObject(string path)
  {
   
object objType = new object();
   
string assemblyPath = string.Empty;
   
string serverComponent = string.Empty;
   GetServerIcoConfig(
out assemblyPath,out serverComponent);
   
   assemblyPath 
= path +"\\"+ assemblyPath;
   
try
   {
    System.Reflection.Assembly a 
= Assembly.LoadFile(assemblyPath);
    objType 
= Assembly.LoadFile(assemblyPath).CreateInstance(serverComponent);//反射创建
   }
   
catch(System.Exception E)
   {
    
throw E;
   }
   
return (IServerVersionInfo) objType;
  }
  
#endregion



在服务器端如需要将系统版本信息保存到数据库,只需要新开发一个继承自IServerVersionInfo接口的组件,并修改相应的XML文件就可以了。

   

 <configSections>       
         
<section name="AutoUpdateIco" type="AutoUpdate.IcoFactory.CustomSectionHandler, AutoUpdate.IcoFactory"/>
     
</configSections>
 
<AutoUpdateIco>
   
<add key="ServerAssembly" value="AutoUpdate.ServerComponent.dll" /><!--实现服务的程序集名-->
         
<add key="ServerComponent" value="AutoUpdate.ServerComponent.XmlFileComponent" /><!--实现服务的类名-->
 
</AutoUpdateIco>

        
            在服务器端,采用了缓存,以提高性能。
            

 1     [WebMethod(Description = "服务器端的版本信息")]
 2         public ServerModel GetSerVersionInfo(string sysname)
 3         {
 4             object objType = ObjectCache.GetCache(sysname);//从缓存读取
 5             string path = Server.MapPath("");
 6             
 7             ObjectInfo objinfo=new ObjectInfo(sysname,path);
 8             
 9             IServerVersionInfo serv = GetIServerVersionInfo(sysname);
10             
11             ServerModel model = serv.GetSerVersionInfo(objinfo);
12             return model;
13         }
14         
15         [WebMethod(Description="要更新的文件列表")]
16         public string[] NewFileFiles(string sysname)
17         {
18             string path = Server.MapPath("");
19             
20             ObjectInfo objinfo=new ObjectInfo(sysname,path);
21             
22             IServerVersionInfo serv = GetIServerVersionInfo(sysname);
23             
24             return serv.NewFileFiles(objinfo);
25         }
26         
27         private IServerVersionInfo GetIServerVersionInfo(string sysname)
28         {
29             object objType = ObjectCache.GetCache(sysname);//从缓存读取
30             if (objType == null)
31             {
32                 try
33                 {
34                     IServerVersionInfo serv = new ServerComponent.XmlFileComponent();
35                     
36                     ObjectCache.SetCache(sysname, serv);// 写入缓存
37                 }
38                 catch
39                 {}
40             }
41             return (IServerVersionInfo)objType;
42         }


        此版本没有考虑到系统内部单个文件的版本更新,这是一个不足的地方,但在目前的系统中已经够用了,等以后有时间再来完善。

posted on 2006-08-21 13:37  舒密  阅读(8725)  评论(29编辑  收藏  举报

导航