这是本人第一次写比较复杂的文章,表达不清之处,请各位见谅。好,闲话少说,入正题。
最近单位开发一个项目,其中需要用到自动升级功能。因为自动升级是一个比较常用的功能,可能会在很多程序中用到,于是,我就想写一个自动升级的组件,在应用程序中,只需要引用这个自动升级组件,并添加少量代码,即可实现自动升级功能。因为我们的程序中可能包含多个exe或者dll文件,所以要支持多文件的更新。
首先,要确定程序应该去哪里下载需要升级的文件。我选择了到指定的网站上去下载,这样比较简单,也通用一些。在这个网站上,需要放置一个当前描述最新文件列表的文件,我们估且叫它服务器配置文件。这个文件保存了当前最新文件的版本号(lastver),大小(size),下载地址(url),本地文件的保存路径(path),还有当更新了这个文件后,程序是否需要重新启动(needRestart)。这个文件大致如下:
updateservice.xml
< updateFiles >
< file path ="AutoUpdater.dll" url ="http://update.iyond.com/CompanyClientApplication/AutoUpdater.zip" lastver ="1.0.0.0" size ="28672" needRestart ="true" />
< file path ="CompanyClient.exe" url ="http://update.iyond.com/CompanyClientApplication/CompanyClient.zip" lastver ="1.1.0.0" size ="888832 " needRestart ="true" />
< file path ="HappyFenClient.dll" url ="http://update.iyond.com/CompanyClientApplication/HappyFenClient.zip" lastver ="1.0.0.0" size ="24576" needRestart ="true" />
< file path ="NetworkProvider.dll" url ="http://update.iyond.com/CompanyClientApplication/NetworkProvider.zip" lastver ="1.0.0.0" size ="32768" needRestart ="true" />
< file path ="Utility.dll" url ="http://update.iyond.com/CompanyClientApplication/Utility.zip" lastver ="1.0.0.0" size ="20480" needRestart ="true" />
< file path ="Wizard.dll" url ="http://update.iyond.com/CompanyClientApplication/Wizard.zip" lastver ="1.0.0.0" size ="24576" needRestart ="true" />
</ updateFiles >
同时,客户端也保存了一个需要升级的本地文件的列表,形式和服务器配置文件差不多,我们叫它本地配置文件。其中,<Enable>节点表示是否启用自动升级功能,<ServerUrl>表示服务器配置文件的地址。
update.config
< Config xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd ="http://www.w3.org/2001/XMLSchema" >
< Enabled > true </ Enabled >
< ServerUrl > http://update.iyond.com/updateservice.xml </ ServerUrl >
< UpdateFileList >
< LocalFile path ="AutoUpdater.dll" lastver ="1.0.0.0" size ="28672" />
< LocalFile path ="CompanyClient.exe" lastver ="1.1.0.0" size ="888832 " />
< LocalFile path ="HappyFenClient.dll" lastver ="1.0.0.0" size ="24576" />
< LocalFile path ="NetworkProvider.dll" lastver ="1.0.0.0" size ="32768" />
< LocalFile path ="Utility.dll" lastver ="1.0.0.0" size ="20480" />
< LocalFile path ="Wizard.dll" lastver ="1.0.0.0" size ="24576" />
</ UpdateFileList >
</ Config >
使用自动各级组件的程序在启动时,会去检查这个配置文件。如果发现有配置文件中的文件版本和本地配置文件中描述的文件版本不一致,则提示用户下载。同时,如果本地配置文件中某些文件在服务器配置文件的文件列表中不存在,则说明这个文件已经不需要了,需要删除。最后,当升级完成后,会更新本地配置文件。
我们先来看一下如何使用这个组件。
在程序的Program.cs的Main函数中:
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault( false );
AutoUpdater au = new AutoUpdater();
try
{
au.Update();
}
catch (WebException exp)
{
MessageBox.Show(String.Format( " 无法找到指定资源\n\n{0} " , exp.Message), " 自动升级 " , MessageBoxButtons.OK, MessageBoxIcon.Error);
}
catch (XmlException exp)
{
MessageBox.Show(String.Format( " 下载的升级文件有错误\n\n{0} " , exp.Message), " 自动升级 " , MessageBoxButtons.OK, MessageBoxIcon.Error);
}
catch (NotSupportedException exp)
{
MessageBox.Show(String.Format( " 升级地址配置错误\n\n{0} " , exp.Message), " 自动升级 " , MessageBoxButtons.OK, MessageBoxIcon.Error);
}
catch (ArgumentException exp)
{
MessageBox.Show(String.Format( " 下载的升级文件有错误\n\n{0} " , exp.Message), " 自动升级 " , MessageBoxButtons.OK, MessageBoxIcon.Error);
}
catch (Exception exp)
{
MessageBox.Show(String.Format( " 升级过程中发生错误\n\n{0} " , exp.Message), " 自动升级 " , MessageBoxButtons.OK, MessageBoxIcon.Error);
}
Application.Run( new MainUI());
}
如上所示,只需要简单的几行代码,就可以实现自动升级功能了。
软件运行截图:
下面,我们来详细说一下这个自动升级组件的实现。
先看一下类图:
AutoUpdater:自动升级的管理类,负责整体的自动升级功能的实现。
Config:配置类,负责管理本地配置文件。
DownloadConfirm:一个对话框,向用户显示需要升级的文件的列表,并允许用户选择是否马上升级。
DownloadFileInfo:要下载的文件的信息
DownloadProgress:一个对话框,显示下载进度。
DownloadProgress.ExitCallBack,
DownloadProgress.SetProcessBarCallBack,
DownloadProgress.ShowCurrentDownloadFileNameCallBack:由于.NET2.0不允许在一个线程中访问另一个线程的对象,所以需要通过委托来实现。
LocalFile:表示本地配置文件中的一个文件
RemoteFile:表示服务器配置文件中的一个文件。
UpdateFileList:一个集合,从List<LocalFile>继承
我们先整体看一下AutoUpdater.cs: