(三) 实现更新
.net应用程序更新组件通过将下载和更新过程分为单独的两个阶段来获得健壮性。当每一阶段都完成时,在位于客户端应用程序目录下的一个更新显式文件(manifest file)中记载下来。如果下载或更新任何一个阶段中的过程被打断,它就会在下一次应用程序启动时从上一次完成的断点继续原来的工作。每一阶段都可以重新运行,因此如果在一个阶段中间出现失败,重新运行该阶段就可以成功。如果有错误发生,比如在下载过程中与服务器的链接丢失,.net更新组件将会在稍后重试。如果报告了非常多的错误(例如web服务器再也没有回到在线状态),下载和更新将会被放弃并且报告出错误。
我们的第一个方法是简单地启动一个单独的进程来实现更新。这个单独的进程将会首先关闭应用程序进程,实现更新(因为这时候已被解锁),重启应用程序进程并且在完成之后关闭自己。因此,这种设计存在三个基本的问题:
. 在某些情况下它不起作用。在更新应用程序时,更新进程关闭原始的应用程序进程,更新进程自身也要被关闭,因此也就不会实现更新。
. 我们希望能够自动更新所有要实现更新的代码。我们希望自动安装修补的能力不仅仅发生在应用程序上,而且.net应用程序更新组件自身也可以。使用这种模式,我们不能更新实现更新的进程。
. 强制用户关闭应用程序并在使用过程中等待,这是很不礼貌的。
用来实现应用程序更新的最后一种方法是使用.net框架并行程序集模式。作为试图更新应用程序自身的替代方案,生成一个比目前存在版本新的应用程序版本。
新版本可以通过合并目前现存的应用程序目录与下载的更新版本来生成。当新版本完成时,用户在下次重新打开应用程序时会自动使用新版本。原始应用程序的拷贝就可以被移除了。棘手问题是弄清在某个指定时刻哪个版本该被载入。我们介绍一个名称为appstart的应用程
序。appstart是进入你应用程序的入口点,使用这种模式,你的应用程序目录看起来是这个样子:..
--> program files
--> myapp
--> appstart.exe
--> appstart.config
--> v1 folder
--> myapp.exe
--> v1.1 folder
--> myapp.exe
要运行你的应用程序,你通常是启动appstart.exe。如果你想在桌面上有个快捷键,那个快捷键必须应该指向appstart而不是直接指向应用程序(注意,你可以重命名appstart.exe 为任何你想要的名字,例如yourapp.exe)appstart.exe是个非常简单的程序,它读取appstart.config文件并且载入指定的应用程序。一个有效appstart.config文件如下所示:
<config>
<appfoldername>v1 folder</appfoldername>
<appexename>myapp.exe</appexename>
<applaunchmode>appdomain</applaunchmode>
</config>
appfoldername指定包含当前要运行的应用程序版本的子文件夹。appexename包含在那个文件夹下要载入的exe文件名。当一个应用程序更新完成时,最后一步就是修改appfoldername的值为指向应用程序的新版本。这样,下次用户运行应用程序时,就会运行新的应用程序更新后的版本。applaunchmode指定如何加载应用程序。有两种方式加载应用程序:第一种方式是使用appdomains。appdomains是.net框架公
用语言运行时的特性,也是独立的逻辑单元和管理对象。公用语言运行时允许每个进程中存在多个应用程序域。这样appstart.exe就能够在单独的appdomain中同时却是相同的appstart.exe进程中加载你的应用程序。尽管事实是两个不同的exe 程序在运行(即appstart.exe和myapp.exe),但只有一个进程在使用。对于大多数应用程序appdomains会工作得很好,当然,在一个单独的appdomain中运行和在一个单独
的进程中运行还是有些细微区别的。在这种情况下,applaunchmode可以设置为“process”,这样就会使应用程序在单独进程中加载。
一旦appstart启动应用程序,它就会进入休眠状态等待应用程序终止。一旦应用程序终止,appstart也会关闭。
三、实例演练
前面我们讨论了.net应用程序更新是如何工作的,现在我们来将它应用在实例中。
第一步:建立应用程序来进行更新
1. 使用vs.net生成一个新的windows应用项目,命名为"sampleapp"。
2. 给窗体一个你选择的有趣的背景色。我们将使用背景色来与后面更新的版本区别。
3. 现在让我们给这个应用程序增加一个细微的功能,首先给你的窗体增加一个按钮。压缩文件中包含一个拥有简单windows窗体的程序集。给压缩文件中samples\sampleapp\simpleform 程序集增加一个引用。然后在你的按钮事件句柄中添加两行代码:
..
simpleform.form1 f = new simpleform.form1();
f.show();
4. 将你的build标志从debug转换为release。这将允许我们避免稍后当我们生成一个应用程序的新版本而同时原始拷贝正在运行产生的pdb文件锁定问题。生成并测试你的应用程序。
第二步:添加.net应用程序更新组件
1. 在vs.net工具栏的组件标签上,右击选择“自定义工具栏”。选择“.net框架组件”标签。点“浏览”并选择位于压缩文件中appupdater 项目下的appupdater.dll,单击ok。
2. 一个appupdater图标现在应该出现在工具栏的组件列表的底部。将appupdater 组件拖放到sampleapp窗体上。一个名为appupdater1的.net应用程序更新组件的实例会出现在窗体的底部。
第三步:设置.net应用程序更新组件
在这一步我们将设置.net应用程序更新组件。注意这个示例你只需改变最开始的四个属性,其它的采用默认值。
appupdater属性:这是.net application应用程序更新的核心,对于本程序需要做以下设置:
(1)autofileload:这个控制后面要描述的命令下载特征,现在将它设置为true。
(2)changedetectionmode:该枚举决定如何为更新进行检查。在该例中,我们将使用一个服务器显式检查,因此将这个值设置为“servermanifestcheck ”。
(3)showdefaultui: .net 应用程序更新组件具有一系列用户界面来通知用户一些事件,比如有一个新的更新可以使用了或者在更新期间发生错误等。这种用户界面可以通过设置默认的用户界面为无效而用自定义应用程序指定的用户界面来代替它,挂钩适当的事件(比如
onupdatecomplete)并弹出自定义用户界面。对于该例我们将使用默认的用户界面,因此将这个值设置为true 。
(4)updateurl :updateurl 是决定更新程序到何处去寻找更新的。在该例中我们使用一个服务器显式文件来检查更新,因此这个属性应当设置为服务器显式文件的url 。
在该例中将它设置为:http://yourwebserver/sampleapp_serversetup/updateversion.xml。请用你的web 服务器名
称来代替“yourwebserver ”。
downloader 属性:appupdater 组件有两个子组件。第一个称之为downloader,它控制组件的下载和poller属性:appupdater的第二个子组件是poller,poller控制更新检查。
(1)autostart:布尔值,在应用程序启动时控制poller 是否应当开始轮询或它是否应当等待直到有计划的更新查询开始。
(2)downloadondetection:布尔值,控制poller 在一个新的更新发现时是否立即开始下载更新,或者是否通过调用downloadudpate() 方法开始显式下载。
(3)initialpollinterval:应用程序启动后在第一次执行更新检查前等待的秒数。
(4)pollinterval:第一次更新检查之后,pollinterval 控制后续每次更新检查之间间隔的秒数,注意:默认为每30 秒进
行一次检查;显然,你会希望你的应用程序减少更新检查的频率。
所有这一切完成之后,你的属性表格看起来应当是下面这个样子:
samples\sampleapp\sampleapp_complete目录包含应用程序正确安装的一个版本。
Java Asp PHP .Net XML C/C++ CGI VB Jsp J2ee J2se J2me EJB Servlet Tomcat Resin Struts Weblogic Eclipse ANT GUI JMS Web servise IDEA Webphere Hibernate Spring Jboss Applet Swing Socket Javamail Perl Ajax P2P 安全 模式 框架 测试 开源 游戏
Windows XP Windows 2000 Windows 2003 Windows Me Windows 9.x Linux UNIX 注册表 操作系统 服务器 应用服务器