代码改变世界

自定义Visual Studio Setup Project的安装必备条件(Prerequisite)

2011-07-31 10:24 by gnorts, ... 阅读, ... 评论, 收藏, 编辑

      我们在编写程序的时候经常会依赖于其他一些已经发布的软件,在软件发布的时候,为了给用户更好的体验,我们洗完能够做到Click-Once Installation。如果用户没有安装我们所依赖的软件,我们将提示用户去官方网站下载并安装。这一点Microsoft Visual Studio Setup Project的Prerequisite可以帮助我们做到。只是Visual Studio自带的Prerequisite数量有限,经常无法满足我们的需求,但是我们可以通过一定步骤来创建自定义的Prerequisite.

      我们以Outlook Social Provider的安装文件为例。Outlook Social Provider是建立在Outlook Social Connector的一个Outlook插件。所以在打包我们自己开发的Outlook Social Provider时,我们希望先行检查系统中是否装有我们支持版本的Outlook和Outlook Social Connector,如果不存在我们支持的Outlook,我们直接退出安装,如果Outlook Social Connector不存在,我们希望自动下载Outlook Social Connector 1.1并自动安装,这就需要在相应的Setup Project中增加Outlook Social Connector 1.1的Prerequisite。然而Visual Studio自带的Prerequisite十分有限,这就需要我们自定义Prerequisite。

      首先,在C:\Program Files\Microsoft SDKs\Windows\v7.0A\Bootstrapper\Packages目录下我们可以看到有很多文件夹,这些文件夹对应了VS2010 Setup Project可用的Prerequisite。我们可以打开任何一个VS Setup Project的Properties窗口,单击Prerequisite按钮(系统必备按钮),在弹出窗口中所显示的列表应该与上述目录下的列表相对应。

      我们可以在上述目录下新建一个文件夹,命名为OutlookSocialConnector1_1,在这个文件夹当中我们将定义我们的Product Manifest和Package Manifest。我们建立Product.xml,内容如下:

Product.xml
 1 <?xml version="1.0" encoding="utf-8"?>
2 <Product
3 xmlns="http://schemas.microsoft.com/developer/2004/01/bootstrapper"
4 ProductCode="OSC.Install_V1.1">
5
6 <RelatedProducts>
7 <DependsOnProduct Code="Microsoft.Windows.Installer.3.1"/>
8 </RelatedProducts>
9
10 <InstallChecks>
11 <!--Outlook Social Connector version-->
12 <RegistryCheck Property="OSCVersion"
13 Key="HKLM\Software\Microsoft\Office\Outlook\SocialConnector"
14 Value="OSCVersion"/>
15 <!--Office version-->
16 <RegistryCheck Property="OfficeVersion"
17 Key="HKLM\Software\Microsoft\Office\Common"
18 Value="LastAccessInstall"/>
19 <!--Outlook 2010 bitness-->
20 <RegistryCheck Property="Outlook14Bitness"
21 Key="HKLM\Software\Microsoft\Office\14.0\Outlook"
22 Value="Bitness"/>
23 </InstallChecks>
24 </Product>

      其中,我们可以在RelatedProducts标签中定义这个程序的依赖关系,上述例子中表示,Outlook Social Connector的安装必须依赖Windows Install version 3.1。而RegistryCheck标签定义了如何通过注册表检查当前安装的Outlook Social Connector以及Microsoft Outlook的版本,这些注册表值将会在Package Manifest中被用到。

      Package Manifest是基于特定语言环境的,他位于以语言命名的子文件夹内。我们在Packages目录下建立一个子文件夹名为en,表示支持local为英文的Outlook Social Connector,在en文件夹下建立Package.xml文件,内容如下:

Package.xml
  1 <?xml version="1.0" encoding="utf-8" ?>
2 <Package
3 xmlns="http://schemas.microsoft.com/developer/2004/01/bootstrapper"
4 Name="Outlook Social Connector v1.1"
5 Culture="en">
6
7 <PackageFiles>
8 <!--G-link to install the latest version of the 32-bit OSC
9 (English version) for Outlook 2003 and Outlook 2007.-->
10 <PackageFile Name="outlooksocialconnector-x86-en-us.exe"
11 HomeSite="http://g.live.com/0cr1033/80"
12 PublicKey="3082010a0282010100bd3089fb4572a8536b9e894f0023c0bed41d3db1594038f373918226e6961200
13 53d91c820e3cce1dbbbdf7428d97d4fc381ae4b9f9e3ecd36103bfa0d3d6754d5c46a9ed5ef0d2e2695b1a73eab31c8d04cd2944a064592f1e
14 985d6ec7ab18398265c4a7bcab758819ea87971426b37f2676a4d4383984e3b326d518f92be9d2c9165a5421f2978d878629fef4492ce68bf8
15 043f7dcdcd9692860d7103e2d0fe0c4235ffd7b83fdd8e450a7df6d74bad5bf076721d77237d8935c41c5db250034b476d07a75588980680a6
16 81ad544ed881d6fabf42c031be550d99d553491230ebe5a5887c5ec47a5a148708b43769a0eb32248c08ebf9d414bae0fccdeaa4150203010001"/>
17 <!--G-link to install the latest version of the 32-bit OSC
18 (English version) for Outlook 2010.-->
19 <PackageFile Name="osc-kb983403-fullfile-x86-en-us.exe"
20 HomeSite ="http://g.live.com/0cr1033/82"
21 PublicKey="3082010a0282010100bd3089fb4572a8536b9e894f0023c0bed41d3db1594038f373918226e696
22 120053d91c820e3cce1dbbbdf7428d97d4fc381ae4b9f9e3ecd36103bfa0d3d6754d5c46a9ed5ef0d2e2695b1a73eab31c8d04cd2944a0
23 64592f1e985d6ec7ab18398265c4a7bcab758819ea87971426b37f2676a4d4383984e3b326d518f92be9d2c9165a5421f2978d878629fe
24 f4492ce68bf8043f7dcdcd9692860d7103e2d0fe0c4235ffd7b83fdd8e450a7df6d74bad5bf076721d77237d8935c41c5db250034b476d
25 07a75588980680a681ad544ed881d6fabf42c031be550d99d553491230ebe5a5887c5ec47a5a148708b43769a0eb32248c08ebf9d414ba
26 e0fccdeaa4150203010001"/>
27 <!--G-link to install the latest version of the 64-bit OSC
28 (English version) for Outlook 2010.-->
29 <PackageFile Name="osc-kb983403-fullfile-x64-en-us.exe"
30 HomeSite ="http://g.live.com/0cr1033/83"
31 PublicKey="3082010a0282010100bd3089fb4572a8536b9e894f0023c0bed41d3db1594038f373918226e69
32 6120053d91c820e3cce1dbbbdf7428d97d4fc381ae4b9f9e3ecd36103bfa0d3d6754d5c46a9ed5ef0d2e2695b1a73eab31c8d04cd2944
33 a064592f1e985d6ec7ab18398265c4a7bcab758819ea87971426b37f2676a4d4383984e3b326d518f92be9d2c9165a5421f2978d87862
34 9fef4492ce68bf8043f7dcdcd9692860d7103e2d0fe0c4235ffd7b83fdd8e450a7df6d74bad5bf076721d77237d8935c41c5db250034b
35 476d07a75588980680a681ad544ed881d6fabf42c031be550d99d553491230ebe5a5887c5ec47a5a148708b43769a0eb32248c08ebf9d
36 414bae0fccdeaa4150203010001"/>
37 </PackageFiles>
38
39 <Commands>
40 <!--Install latest OSC for Outlook 2003.-->
41 <Command PackageFile="outlooksocialconnector-x86-en-us.exe">
42 <InstallConditions>
43 <!--Install if the OSC version is less than 1.1 and
44 the Office version is 2003.-->
45 <BypassIf Property="OSCVersion" Compare="VersionGreaterThanOrEqualTo" Value="1.1"/>
46 <BypassIf Property="OfficeVersion" Compare="ValueNotExists"/>
47 <BypassIf Property ="OfficeVersion" Compare="ValueNotEqualTo" Value="11.0"/>
48 </InstallConditions>
49 <ExitCodes>
50 <ExitCode Value="0" Result="Success"/>
51 <ExitCode Value="1641" Result="SuccessReboot"/>
52 <ExitCode Value="3010" Result="SuccessReboot"/>
53 <DefaultExitCode Result="Fail" String="GeneralFailure"/>
54 </ExitCodes>
55 </Command>
56 <!--Install latest OSC for Outlook 2007.-->
57 <Command PackageFile="outlooksocialconnector-x86-en-us.exe">
58 <InstallConditions>
59 <!--Install if the OSC version is less than 1.1 and
60 the Office version is 2007.-->
61 <BypassIf Property="OSCVersion" Compare="VersionGreaterThanOrEqualTo" Value="1.1"/>
62 <BypassIf Property="OfficeVersion" Compare="ValueNotExists"/>
63 <BypassIf Property ="OfficeVersion" Compare="ValueNotEqualTo" Value="12.0"/>
64 </InstallConditions>
65 <ExitCodes>
66 <ExitCode Value="0" Result="Success"/>
67 <ExitCode Value="1641" Result="SuccessReboot"/>
68 <ExitCode Value="3010" Result="SuccessReboot"/>
69 <DefaultExitCode Result="Fail" String="GeneralFailure"/>
70 </ExitCodes>
71 </Command>
72 <!--Install latest OSC for Outlook 2010 32-bit.-->
73 <Command PackageFile="osc-kb983403-fullfile-x86-en-us.exe">
74 <InstallConditions>
75 <!--Install if the OSC version is less than 1.1 and
76 the Office version is 2010 and
77 Office is 32-bit.-->
78 <BypassIf Property="OSCVersion" Compare="VersionGreaterThanOrEqualTo" Value="1.1"/>
79 <BypassIf Property="OfficeVersion" Compare="ValueNotExists"/>
80 <BypassIf Property ="OfficeVersion" Compare="ValueNotEqualTo" Value="14.0"/>
81 <BypassIf Property ="Outlook14Bitness" Compare="ValueNotEqualTo" Value="x86"/>
82 </InstallConditions>
83 <ExitCodes>
84 <ExitCode Value="0" Result="Success"/>
85 <ExitCode Value="1641" Result="SuccessReboot"/>
86 <ExitCode Value="3010" Result="SuccessReboot"/>
87 <DefaultExitCode Result="Fail" String="GeneralFailure"/>
88 </ExitCodes>
89 </Command>
90 <!--Install latest OSC for Outlook 2010 64-bit-->
91 <Command PackageFile="osc-kb983403-fullfile-x64-en-us.exe">
92 <InstallConditions>
93 <!--Install if the OSC version is less than 1.1 and
94 the Office version is 2010 and
95 Office is 64-bit.-->
96 <!--NOTE: 64-bit versions of Office run only on 64-bit
97 versions of Windows. For 64-bit versions of Windows,
98 you must create an executable that evaluates the
99 64-bit registry keys and modify the Product.xml file to
100 use an ExternalCheck to evaluate the results. Then
101 modify these InstallConditions to use the results.-->
102 <BypassIf Property="OSCVersion" Compare="VersionGreaterThanOrEqualTo" Value="1.1"/>
103 <BypassIf Property="OfficeVersion" Compare="ValueNotExists"/>
104 <BypassIf Property ="OfficeVersion" Compare="ValueNotEqualTo" Value="14.0"/>
105 <BypassIf Property ="Outlook14Bitness" Compare="ValueNotEqualTo" Value="x64"/>
106 </InstallConditions>
107 <ExitCodes>
108 <ExitCode Value="0" Result="Success"/>
109 <ExitCode Value="1641" Result="SuccessReboot"/>
110 <ExitCode Value="3010" Result="SuccessReboot"/>
111 <DefaultExitCode Result="Fail" String="GeneralFailure"/>
112 </ExitCodes>
113 </Command>
114 </Commands>
115 </Package>

      在Package标签中,Name属性定义了这个Prerequisite在Visual Studio中显示的名称,Culture属性值必须与你的这个文件夹所在的目录名称一样。Package标签下包含了一组PackageFile,这些PackageFile是在不同环境下所需要的安装包得描述,包括它们的PublicKey已经它们的下载地址HomeSite

      之后的Commands标签定义了在不同环境下选择不同的PackageFile进行安装。注意:上述代码是微软官方文档中给出的example,但是在使用过程中却出现了问题,PackageFile的安装界面可能无法出现,但是查看进程却发现这个进程已经启动。如果需要安装的PackageFile需要用户进行操作,那么安装的页面将会卡死在这一步。我的解决方案是这样:Command标签有一个属性叫Arguments可以在这个属性中设置PackageFile启动的Parameter,我设置的是Argument=”/quiet”,在silent模式下进行安装,测试结果表示能够成功安装所选择的PackageFile。至于怎么查看可用的Parameter,可以在控制台下使用命令:<PackageFileName> /?可以查看到所有可用的启动参数。

     其次就是PublicKey必须在一行中写完,如果分为多行,系统会将换行符也算进去,会导致下载包得PublicKey与我们定义的不一样,在安装过程中就会报错。

     做完这些我们重新打开VS Setup Project的Prerequisite窗口,就能在那个列表中看到我们定义的Outlook Social Connector一项了。