私有部署应用程序升级策略一文中采用用户手工管理的方式升级功能,但这样使用并不方便,需要用户参与操作,那么有没有一键安装的方式呢。有,那就是发布者控制策略,在一键安装时,将需要升级的策略生成到GAC中,将升级文件(DLL或者exe)安装到应用程序基目录或者GAC中。
本文中的内容跟《私有部署应用程序升级策略》具有相关性,请读者先阅读前一篇文章。私有部署应用程序升级策略
软件运行时调用版本为1.0.0.1的SomeMethodLib程序集,CLR首先尝试访问GAC,如果GAC中找不到再从应用程序基目录中查找。当CLR尝试从GAC加载是发现对应的发布者策略控制,将按照策略中的方式加载SomeMethodLib程序集。
下面,我们自己动手创建一个控制策略。
1、在SomeMethodLib中新建App.config文件,文件内容如代码1所示。注意这里不能使用probing或者publisherPolicy元素。
代码1描述了应用程序依赖一个名字叫SomeMethodLib密钥为1217633aa9436597语言文化为neutral的程序集,遇到旧版本为1.0.0.1到1.0.0.3时将使用新版本2.0.0.0。codeBase提供了2.0.0.0版本的位置。
代码1 App.config
<?xml version="1.0" encoding="utf-8" ?> <configuration> <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity type="win32" name="SomeMethodLib" publicKeyToken="1217633aa9436597" culture="neutral"/> <bindingRedirect oldVersion="1.0.0.1-1.0.0.3" newVersion="2.0.0.0"/> <!—codeBase标识的href要求CLR能识别,如下面所示的这种方式无法正确运行,可采用如同href=http://www.****.com/ SomeMethodLib.dll的方式 <codeBase version="2.0.0.0" href="V20/SomeMethodLib.dll"/>--> </dependentAssembly> </assemblyBinding> </runtime> </configuration>
2、通过AL.exe创建控制策略Dll文件。
al /out:Policy.1.0.SomeMethodLib.dll
/Version:1.0.0.1
/keyfile:succeed.snk
/linkresource:app.config
注释:
/out Al.exe创建一个除了清单之外什么都没有的PE。程序集名称很重要。
第一部分Policy 告诉CLR该程序集包含发布者策略信息。
第二三部分 1.0 告诉CLR这个发布者策略适用于major和minor为1.0的任何SomeMethodDll程序集。发布者策略只能与major和minor相关联与build和revision无关。
第四部分 SomeMethodLib致命发布者策略对应的程序集名称。
第五部分 dll是要声称的发布者策略程序集文件的扩展名
/version: 标识发布者策略程序集版本。与SomeMethodLib版本没有关系。CLR根据/version指定的版本号选择最新版本发布者策略程序集。
/keyfile 这个密钥对必须匹配于所有SomeMethodLib程序集的密钥对。
/linkresource 将.config文件作为资源链接到程序集。最后的程序集由Policy.1.0.SomeMethodLib.dll和app.config两个文件组成,这两个文件必须随同新版本程序集打包部署到用户机器上。
3、将发布者策略程序集安装到GAC中
文件Policy.1.0.SomeMethodLib.dll和app.config被自动放置到C:\Windows\Microsoft.NET\assembly\**下的某一文件夹中
4、代码1提到了codeBase如果采用指定某一网络的方式是可以的,作为测试也可以指定绝对路径,但是无法使用基于当前应用程序的相对路径,因为GAC中的Dll文件不知道应用程序安装在哪一个位置。(这个问题有待解决)目前采用一种替代方案:
将SomeMethodLib.dll安装到GAC中:
5、看一下代码2DeployTest.exe.configure内容(当然也可以没有这个文件,关于这个文件的解释请查看《私有部署应用程序升级策略》)
代码2 DeployTest.exe.configure
<?xml version="1.0" encoding="utf-8" ?> <configuration> <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <probing privatePath="NoSN;V1;V2;V3"/> <dependentAssembly> <assemblyIdentity type="win32" name="SomeMethodLib" publicKeyToken="1217633aa9436597" culture="neutral"/> <bindingRedirect oldVersion="1.0.0.1-1.0.0.2" newVersion="1.0.0.3"/> <codeBase version="1.0.0.3" href="V3/SomeMethodLib.dll"/> <!--<publisherPolicy apply="no"/>--> </dependentAssembly> </assemblyBinding> </runtime> </configuration>
测试DeployTest.exe能否正确运行
可以看出,这里的确运行的不是1.0.0.1到1.0.0.3的版本而是版本2.0.0.0。
基本已达到发布者控制策略而用户不参与的目的。可是代码2中被屏蔽的一行是做什么用的?
publisherPolicy是交给用户管理者的管理权限,如果发布者策略发布的版本不好用,管理者可以将apply属性设置为no达到屏蔽发布者策略的目的。下图是设置<publisherPolicyapply="no"/>后DeployTest.exe的运行结果界面。
从图中可以看出,DeployTest引用的是版本1.0.0.3而不是发布者策略规定的2.0.0.0。
7、卸载发布者策略和GAC中的程序集
当用户卸载应用程序时,可通过调用Gacutil.exe /u Application卸载GAC中的发布者策略和程序集。
注意:使用Gacutil.exe /u卸载时,如果GAC中存在重名程序集会导致重名的程序集都被卸载。因此可采用包含版本号、密钥对在内的程序集全名称。