单包创作示例

示例 PUASample.msi 演示了能够在 Windows Server 2008 R2 和 Windows 7 上的每用户或每计算机安装上下文中安装的双用途 Windows Installer 5.0 包。 此示例包遵循单包创作中描述的开发指南。

获取示例的副本

可在适用于 Windows Installer 开发人员的 Windows SDK 组件中获取此示例的副本和 Windows Installer 数据库表编辑器 (Orca.exe)。 示例和表编辑器以 Windows Installer 安装文件 PUASample1.msi 和 Orca.msi 的形式,随 Windows Server 2008 R2 和 Windows 7 的 Windows 软件开发包一起提供。

系统要求

数据库编辑器 Orca.exe 需要 Windows Server 2008 R2(及更低版本)和 Windows 7(及更低版本)。 双用途包 (PUASample1.msi) 可安装在 Windows Server 2008 R2 和 Windows 7 上的每计算机或每用户安装上下文中。 PUASample1.msi 只能安装在 Windows Server 2008(及更低版本)和 Windows Vista(及更低版本)上的每计算机上下文中。 可以安装数据库编辑器来检查 PUASample1.msi 的内容,而无需安装示例。 若要安装示例包或编辑器包,请确保 DisableMSI 策略未设置为阻止应用程序安装的值。

标识双用途包

双用途包应将 MSIINSTALLPERUSER 属性的值初始化为 1。 这会将包标识为能够安装在 Windows Server 2008 R2 和 Windows 7 上的每计算机或每用户上下文中。 只有当已按照单包创作中描述的开发准则编写包,并且你打算为用户提供在每用户或每计算机上下文中安装包的选项时,才在包中设置 MSIINSTALLPERUSER 属性。 双用途包还应将 ALLUSERS 属性的值初始化为 2。 这会将“每用户”指定为应用程序的默认安装上下文。 如果 ALLUSERS 属性的值不是 2,Windows Installer 将忽略 MSIINSTALLPERUSER 属性。

使用 Windows Installer 数据库编辑器(如 Orca.exe)检查 PUASample1.msi 的内容。 示例包中的 Property 表包含下面两个条目。

Property 表(部分)

属性 “值”
ALLUSERS 2
MSIINSTALLPERUSER 1

 

安装上下文的自定义对话框

示例包的用户界面中有自定义对话框 VerifyReadyDialog 的示例,用户可通过该对话框在安装时选择“每用户”或“每计算机”安装上下文。 Dialog 表包含描述 VerifyReadyDialog 对话框的记录。 “属性”字段中输入的值为 39,因为此对话框使用 msidbDialogAttributesVisible (1)、msidbDialogAttributesModal (2)、msidbDialogAttributesMinimize (4) 和 msidbDialogAttributesTrackDiskSpace (32) 对话框样式位。 对话框的标题栏显示 ProductName 属性的值给出的标题。

Dialog 表(部分)

对话框 HCentering VCentering 宽度 高度 特性 标题 Control_First Control_Default Control_Cancel
VerifyReadyDialog 50 50 480 280 39 [ProductName] InstallPerUser 下一步 取消

 

Control 表包含 VerifyReadyDialog dialog 对话框显示的控件对应的条目。 该对话框显示 PushButton 控件和一个 Text 控件。 所有控件都使用 msidbControlAttributesEnabled (2) 和 msidbControlAttributesVisible (1) 控件属性。 InstallPerMachine 控件还使用 ElevationShield 控件属性 msidbControlAttributesElevationShield (8388608)。此控件属性将用户帐户控制 (UAC) 提升图标(盾牌图标)添加到 InstallPerMachine 控件,并通知用户在每计算机上下文中安装应用程序需要 UAC 凭据。 Control 表的“文本”字段中的值是控件显示的文本样式和文本。 若要详细了解如何使用预定义样式向控件添加文本,请查看 [Control 表中“本文”字段的说明] 主题。

Control 表(部分)

Dialog_ 控制 类型 Attribute 文本 Control_Next
VerifyReadyDialog 取消 PushButton 3 {\Tahoma10}取消(&C) 下一步
VerifyReadyDialog 上一篇 PushButton 3 {\Tahoma10}上一个(<<&P) 取消
VerifyReadyDialog 下一步 PushButton 3 {\Tahoma10}下一个(&N) >> InstallPerUser
VerifyReadyDialog Text2 文本 3 是否准备好完成挂起的安装?
VerifyReadyDialog InstallPerUser PushButton 3 {\Tahoma10}仅为我安装(&M) InstallPerMachine
VerifyReadyDialog InstallPerMachine PushButton 8388611 {\Tahoma10}为所有人安装(&E) 上一篇
VerifyReadyDialog 取消 PushButton 3 {\Tahoma10}取消(&C) 下一步

 

ControlEvent 表指定当用户与控件交互时安装程序执行的 ControlEvent 或操作。 当用户激活 InstallPerUser 按键时,用户界面显示 OutOfDisk 对话框(如果 OutOfDiskSpace 属性为 1),将 MSIINSTALLPERUSER 属性的值设置为 1,将 ALLUSERS 属性的值设置为 2,将 MSIFASTINSTALL 属性的值设置为 1,并返回去。 由于设置了 MSIFASTINSTALL 属性,因此不会为安装生成系统还原点。 当用户激活 InstallPerMachine 按键时,用户界面显示 OutOfDisk 对话框(如果 OutOfDiskSpace 属性为 1),将 ALLUSERS 属性的值设置为 1,并返回去。

ControlEvent 表(部分)

Dialog_ Control_ 事件 参数 条件 订单
VerifyReadyDialog InstallPerUser SpawnDialog OutOfDisk OutOfDiskSpace = 1 1
VerifyReadyDialog InstallPerUser EndDialog 返回 OutOfDiskSpace <> 1 5
VerifyReadyDialog InstallPerUser [MSIINSTALLPERUSER] 1 1 2
VerifyReadyDialog InstallPerUser [ALLUSERS] 2 1 3
VerifyReadyDialog InstallPerMachine SpawnDialog OutOfDisk OutOfDiskSpace = 1 1
VerifyReadyDialog InstallPerMachine EndDialog 返回 OutOfDiskSpace <> 1 3
VerifyReadyDialog InstallPerMachine [ALLUSERS] 1 1 2
VerifyReadyDialog InstallPerUser [MSIFASTINSTALL] 1 1 4

 

应使用低于 Windows Installer 5.0 的 Windows Installer 版本从任何安装项的用户界面中移除 InstallPerUser 控件。 示例包中的 ControlCondition 表包含 4 个条目,如果当前版本低于 Windows Installer 5.0,则禁用和隐藏 InstallPerUser 控件。 该表使用 VersionMsi 属性的值和条件语句语法来定义此条件。 仅当“条件”字段中的语句为 true 时,才会执行“操作”字段中指定的操作。

ControlCondition 表(部分)

Dialog_ Control_ 操作 条件
VerifyReadyDialog InstallPerUser 启用 VersionMsi >= "5.00"
VerifyReadyDialog InstallPerUser 禁用 VersionMsi < "5.00"
VerifyReadyDialog InstallPerUser 显示 VersionMsi >= "5.00"
VerifyReadyDialog InstallPerUser 隐藏 VersionMsi < "5.00"

 

指定目录结构

使用数据库编辑器检查 PUASample1.msi 的 Directory 表。 Directory 表在其 Directory_Parent 字段中具有空字符串的记录表示源目录树和目标目录树的根目录。 如果未定义 TARGETDIR 属性,安装程序会在安装时将其值设置为 ROOTDRIVE 属性的值。 如果未定义 SourceDir 属性,安装程序会将其值设置为包含 Windows Installer 包(.msi 文件)的目录的位置。目录名称使用 short|long 格式指定。

Directory 表(部分)

目录 Directory_Parent DefaultDir
TARGETDIR SourceDir
ProgramFilesFolder TARGETDIR .
ProgramMenuFolder TARGETDIR .
INSTALLLOCATION MyVendor Sample1|MSDN-PUASample1
MyVendor ProgramFilesFolder Msft|Microsoft

 

在源中,此 Directory 表解析为以下目录路径。

\[SourceDir\]\\Msft\\Sample1 \[SourceDir\]

在目标中,Directory 表解析为下表中的路径。 安装程序将 ProgramFilesFolderProgramMenuFolder 属性的值设置为位置,具体位置取决于安装上下文以及系统是 Windows Server 2008 R2 和 Windows 7 的 32 位版本还是 64 位版本。 目标文件夹的路径取决于用户是选择每用户安装还是每计算机安装。

安装上下文 系统 示例路径
每计算机 Windows Server 2008 R2 和 Windows 7
32 位版本
%ProgramFiles%\Msft\Sample1
%ALLUSERSPROFILE%\Microsoft\Windows\Start Menu\Programs
每计算机 Windows Server 2008 R2 和 Windows 7
64 位版本
%ProgramFiles(x86)%\Msft\Sample1
%ALLUSERSPROFILE%\Microsoft\Windows\Start Menu\Programs
每用户 Windows Server 2008 R2 和 Windows 7
32 位或 64 位版本
%USERPROFILE%\AppData\Local\Programs\Msft\Sample1
%APPDATA%\Microsoft\Windows\Start Menu\Programs

 

每用户应用程序应存储在 ProgramFilesFolder 属性的值指定的 Programs 文件夹下的子文件夹中。 通常,应用程序的路径采用以下形式。

%LOCALAPPDATA%\Programs\ISV name\AppName。

每用户配置数据应存储在由 ProgramMenuFolder 属性的值指定的 Programs 文件夹中。 通常,此文件夹位于以下路径。

%APPDATA%\Microsoft\Windows\Start Menu\Programs

如果安装 32 位 Windows Installer 包组件,请使用 Directory 表中的 ProgramFilesFolderCommonFilesFolder 属性。 如果安装 64 位 Windows Installer 包组件,请使用 ProgramFiles64FolderCommonFiles64Folder 属性。 如果应用程序包含 32 位和 64 位版本的同一同名组件,请确保这些版本保存在不同的目录中或为其指定不同的名称。

下面的 Directory 表提供了与包兼容的目录布局示例,该包包含 32 位和 64 位组件,还包含一些跨应用程序共享的组件。

目录 Directory_Parent DefaultDir
TARGETDIR SourceDir
ProgramFilesFolder TARGETDIR .:Prog32
ProgramFiles64Folder TARGETDIR .:Prog64
CommonFilesFolder TARGETDIR .:Share32
CommonFiles64Folder TARGETDIR .:Share64
ProgramMenuFolder TARGETDIR .:Sample1|MSDN-PUASample1
INSTALLLOCATION MyVendor Sample1|MSDN-PUASample1
INSTALLLOCATIONX64 Vendorx64 Sample1|MSDN-PUASample1
SHAREDLOCATION ShVendor Sample1|MSDN-PUASample1
SHAREDLOCATIONX64 ShVendorx64 Sample1|MSDN-PUASample1
MyVendor ProgramFilesFolder Msft|Microsoft
Vendorx64 ProgramFiles64Folder Msft|Microsoft
ShVendor CommonFilesFolder Msft|Microsoft
ShVendorx64 CommonFiles64Folder Msft|Microsoft
Shrx86 SHAREDLOCATION x32|32-bit components
Shrx64 SHAREDLOCATIONX64 x64|64-bit components
Binx86 INSTALLLOCATION x32|32-bit components
Binx64 INSTALLLOCATIONX64 x64|64-bit components
App32 Binx86 myapp|unshared 32-bit components
App64 Binx64 myapp|unshared 64-bit components
Share32 Shrx86 shared|shared 32-bit components
Share64 Shrx64 shared|shared 64-bit components

 

在源中,此 Directory 表解析为以下目录路径。

\[SourceDir\]Prog32\\Msft\\Sample1\\x32\\myapp \[SourceDir\]Share32\\Common Files\\Msft\\Sample1\\x32\\shared \[SourceDir\]Prog64\\Msft\\Sample1\\x64\\myapp \[SourceDir\]Share64\\Common Files\\Msft\\Sample1\\x64\\shared \[SourceDir\]Sample1

在目标中,此 Directory 表解析为以下目录路径。 目标路径由安装上下文和系统决定。

安装上下文 系统 示例路径
每计算机 Windows Server 2008 R2 和 Windows 7
32 位版本
%ProgramFiles%\Msft\Sample1\x32\myapp
%ProgramFiles%\Common Files\Msft\Sample1\x32\shared
%ProgramFiles(x86)%\Msft\Sample1\x64\myapp
%ProgramFiles(x86)%\Common Files\Msft\Sample1\x64\shared
%ProgramData%\Microsoft\Windows\Start Menu\Programs\Sample1
每计算机 Windows Server 2008 R2 和 Windows 7
64 位版本
%ProgramFiles(x86)%\Msft\Sample1\x32\myapp
%ProgramFiles(x86)%\Common Files\Msft\Sample1\x32\shared
%ProgramFiles%\Msft\Sample1\x64\myapp
%ProgramFiles%\Common Files\Msft\Sample1\x64\shared
%ProgramData%\Microsoft\Windows\Start Menu\Programs\Sample1
每用户 Windows Server 2008 R2 和 Windows 7
32 位或 64 位版本
%LOCALAPPDATA%\Programs\Msft\Sample1\x32\myapp
%LOCALAPPDATA%\Programs\Common\Msft\Sample1\x32\shared
%LOCALAPPDATA%\Programs\Msft\Sample1\x64\myapp
%LOCALAPPDATA%\Programs\Common\Msft\Sample1\x64\shared
%APPDATA%\Microsoft\Windows\Start Menu\Programs\Sample1

 

应用程序注册

PUASample.msi 向应用程序的“应用路径”注册表项添加一个子项并执行注册,使应用程序信息能够保存在此键下的注册表中。 有关应用路径和应用程序注册的详细信息,请在 Shell 开发人员指南Shell 扩展性部分查看 PerceivedTypes、SystemFileAssociations 和应用程序注册。 在安装时,用户决定是在每用户安装上下文还是每计算机安装上下文中安装应用程序。 创作双用途包时,包开发人员无法知道是应在 HKEY_LOCAL_MACHINE 键还是 HKEY_CURRENT_USER 键下执行注册。

包开发人员在 File 表的“文件”字段中定义应用程序可执行文件的文件标识符。

File 表(部分)

文件 Component_ FileName FileSize 版本 语言 特性 序列
MyAppFile ProductComponent PUASAMP1.EXE|PUASample1.exe 81920 0 1

 

可在 Registry 表的“值”字段中将要保存到注册表的值指定为 Formatted 字符串。 使用在 File 表的“文件”字段中定义的文件标识符和 Formatted 类型的 [#filekey] 约定来指定“应用路径”注册表项的默认值。 顶层的 INSTALL 操作执行 InstallExecuteSequence 表中的操作。 完成此表中的 CostInitializeFileCostInstallFinalize 操作后,Windows Installer 会将 Registry 表中的格式化子字符串 [#MyAppFile] 替换为应用程序文件的完整路径。

此示例定义了一个自定义属性 RegRoot 来包含根键的位置,并在用户选择每计算机安装时使用自定义操作重置属性值。 在引用根位置的任何格式化字符串值中使用自定义属性 RegRoot。 在 Property 表中,PUASample.msi 包定义了自定义属性并将 RegRoot 的值设置为 HKCU。 这会初始化每用户安装上下文的属性的值 - 此上下文是建议用于双用途包的默认上下文。

Property 表(部分)

属性 “值”
RegRoot HKCU

 

CustomAction 表中,包定义了一个名为 Set_RegRoot_HKLM 的自定义操作。 “类型”字段中的值将此项标识为自定义操作类型 51 这一标准自定义操作。 CustomAction 表中“源”和“目标”字段的含义由自定义操作类型决定。 若要详细了解自定义操作的标准类型,请参阅自定义操作类型。 Set_RegRoot_HKLM 自定义操作的“源”字段指定了 RegRoot 属性的值。 如果安装程序执行 Set_RegRoot_HKLM 自定义操作,这会将 RegRoot 属性的值重置为 HKLM。

CustomAction 表(部分)

操作 类型 目标
Set_RegRoot_HKLM 51 [RegRoot] HKLM

 

顶层的 INSTALL 操作按 InstallExecuteSequence 表的“序列”字段中指定的序列执行该表中的操作。 在 Set_RegRoot_HKLM 自定义操作 (1501) 的“序列”字段中创作的值指定在 InstallInitialize 操作 (1500) 之后、ProcessComponents 操作 (1600) 之前执行此自定义操作。此序列确保在安装时评估 Set_RegRoot_HKLM 自定义操作的记录。 若要详细了解 InstallExecuteSequence 表中建议的操作序列,请参阅建议的 InstallExecuteSequence 主题。 在“条件”字段中创作的条件语句语法指定,只有当 ALLUSERS 属性的值在安装时计算结果为 1 时才执行 Set_RegRoot_HKLM 操作。 如果 ALLUSERS 属性值为 1,则指定每计算机安装。

InstallExecuteSequence 表(部分)

操作 条件 序列
Set_RegRoot_HKLM ALLUSERS=1 1501

 

如果安装了 ProductComponent 组件,Registry 表中的以下记录将执行注册。 要在 HKEY_LOCAL_MACHINE 下和 HKEY_CURRENT_USER 下为每用户安装执行注册,“根”字段中的值必须为 -1。 “注册表”字段中具有空字符串的记录会在“应用路径”注册表项下为应用程序添加一个子项,并将“(默认)”值设置为应用程序可执行文件的完整路径。 MyAppPathAlias 注册会将可执行文件映射到应用程序别名;如果用户在命令行提示符下键入别名“puapct”,则可以启动应用程序。 MyAppPathRegistration 注册将可执行文件的名称映射到文件的完整路径。

注册表 Root 名称 “值” 组件
-1 Software\Microsoft\MyAppPathRegistrationLocation [RegRoot]\Software\Microsoft\Windows\CurrentVersion\App Paths\PUAPCT.exe ProductComponent
MyAppPathAlias -1 Software\Microsoft\Windows\CurrentVersion\App Paths\PUAPCT.exe [#MyAppFile] ProductComponent
MyAppPathRegistration -1 Software\Microsoft\Windows\CurrentVersion\App Paths\PUASample1.exe [#MyAppFile] ProductComponent

 

自动播放取消注册

PUASample.msi 会执行注册,使应用程序用户能够阻止所选设备启动硬件自动播放。 若要了解如何注册处理程序以取消自动播放来响应事件,请在 Shell 开发人员指南shell 扩展性部分中,查看准备用于自动播放的硬件和软件主题。 以下记录会注册安装 ProductComponent component 组件时在“名称”字段中指定的处理程序。 若要向 Windows Installer 指定注册应重定向到依赖于安装上下文的位置,“根”字段中的值必须为 -1。

Registry

注册表 Root 名称 “值” 组件
MyAutoplayCancelRegistration -1 SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\AutoplayHandlers\CancelAutoplay\CLSID 66A32FE6-229D-427b-A608-D273F40C034C ProductComponent

 

预览控件注册

PUASample.msi 会执行安装预览控件所需的注册,该控件在没有启动应用程序的情况下启用 .pua 文件的只读预览。 有关注册预览控件的信息,请在 Shell 开发人员指南shell 扩展性部分中查看注册预览控件主题。 如果安装了 ProductComponent 组件,Registry 表中的以下记录将执行处理程序。 若要向 Windows Installer 指定注册应重定向到依赖于安装上下文的位置,“根”字段中的值必须为 -1。

Registry

注册表 Root 名称 “值” 组件
MyPreviewHandlerRegistration1 -1 Software\Classes\.pua puafile ProductComponent
MyPreviewHandlerRegistration2 -1 Software\Microsoft\Windows\CurrentVersion\PreviewHandlers {1531d583-8375-4d3f-b5fb-d23bbd169f22} Microsoft Windows PUA TEST 预览控件 ProductComponent
MyPreviewHandlerRegistration3 -1 Software\Classes\puafile\ShellEx\{8895b1c6-b41f-4c1c-a562-0d564250836f} {1531d583-8375-4d3f-b5fb-d23bbd169f22} ProductComponent
MyPreviewHandlerRegistration4 -1 Software\Classes\CLSID\{1531d583-8375-4d3f-b5fb-d23bbd169f22} 每用户应用程序示例 1 预览控件 ProductComponent
MyPreviewHandlerRegistration5 -1 Software\Classes\CLSID\{1531d583-8375-4d3f-b5fb-d23bbd169f22} AppID {6d2b5079-2f0b-48dd-ab7f-97cec514d30b} ProductComponent
MyPreviewHandlerRegistration6 -1 Software\Classes\CLSID\{1531d583-8375-4d3f-b5fb-d23bbd169f22} DisplayName @shell32,-38242 ProductComponent
MyPreviewHandlerRegistration7 -1 Software\Classes\CLSID\{1531d583-8375-4d3f-b5fb-d23bbd169f22} 图标 notepad.exe,2 ProductComponent
MyPreviewHandlerRegistration8 -1 Software\Classes\CLSID\{1531d583-8375-4d3f-b5fb-d23bbd169f22}\InProcServer32 ThreadingModel 单元 ProductComponent
MyPreviewHandlerRegistration9 -1 Software\Classes\CLSID\{1531d583-8375-4d3f-b5fb-d23bbd169f22}\InProcServer32 #%%SystemRoot%\system32\shell32.dll ProductComponent
MyPreviewHandlerRegistration10 -1 Software\Classes\CLSID\{1531d583-8375-4d3f-b5fb-d23bbd169f22}\InProcServer32 ProgID puafile ProductComponent