单包创作示例
示例 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 表解析为下表中的路径。 安装程序将 ProgramFilesFolder 和 ProgramMenuFolder 属性的值设置为位置,具体位置取决于安装上下文以及系统是 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 表中的 ProgramFilesFolder 和 CommonFilesFolder 属性。 如果安装 64 位 Windows Installer 包组件,请使用 ProgramFiles64Folder 和 CommonFiles64Folder 属性。 如果应用程序包含 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 表中的操作。 完成此表中的 CostInitialize、FileCost 和 InstallFinalize 操作后,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 |