我正在使用 WiX 3.7 编写安装程序。安装程序将安装一个旧的 VB6 程序(它是一个供应商专有程序,我没有源代码)。因此,该程序使用了一些未随最新版本的 Windows 安装的旧 COM 库(例如 Windows 7 及更高版本——不确定 Vista 或 XP)。
由于我最近了解到 COM 库现在可以使用免注册 COM 注册来私下安装而无需全局系统注册,这正是我打算为那些不再随 Windows 操作系统分发的 COM 库所做的。
为此,我创建了所需的清单文件,这些文件将用于在应用程序加载和使用库时查找所有 COM 注册信息。我为这些库创建了 MSI 组件。这是这两个库的相关 WiX 标记(我已经删除了组件的 GUID,因此没有人为自己的安装程序复制它们):
<Component Id="C__MsComm32.ocx" Guid="PUT-YOUR-GUID-HERE" DiskId="1">
<File Id="F__MsComm32.ocx" Vital="yes" KeyPath="yes"
Assembly="win32"
AssemblyApplication="F__MyApp.exe"
AssemblyManifest="F__MsComm32.sxs.manifest"
Name="mscomm32.ocx" Source="[to be filled in]" />
<File Id="F__MsComm32.sxs.manifest" Vital="yes" KeyPath="no"
Name="mscomm32.sxs.manifest" Source="[to be filled in]" />
</Component>
<Component Id="C__threed32.ocx" Guid="PUT-YOUR-GUID-HERE" DiskId="1">
<File Id="F__threed32.ocx" Vital="yes" KeyPath="yes"
Assembly="win32"
AssemblyApplication="F__MyApp.exe"
AssemblyManifest="F__threed32.sxs.manifest"
Name="threed32.ocx" Source="[to be filled in]" />
<File Id="F__threed32.sxs.manifest" Vital="yes" KeyPath="no"
Name="threed32.sxs.manifest" Source="[to be filled in]" />
</Component>
为了使所有这些工作,我还需要为应用程序可执行文件提供一个清单文件,称为MyApp.exe.manifest
告诉操作系统此应用程序依赖于哪些程序集。所以我还创建了必要的清单文件。现在我需要创建一个(或多个)用于部署应用程序及其清单的组件。
根据 VS 智能感知File/@Assembly
:
指定此文件是需要安装到全局程序集缓存 (GAC) 中的 Win32 程序集还是 .NET 程序集。如果值为“.net”或“win32”,该文件也必须是组件的关键路径。
然后,对于File/@AssemblyManifest
:
指定描述程序集的清单文件的文件标识符。清单应与其描述的程序集位于同一组件中。只有在将 Assembly 属性设置为“.net”或“win32”时才能指定此属性。
这一切都很好,我完全理解这一切。因此,对于我File
在 WiX 中的应用程序元素,到目前为止,我有这个:
<File Id="F__MyApp.exe" Vital="yes" KeyPath="yes"
Assembly="win32"
AssemblyManifest="F__MyApp.exe.manifest" />
现在,我不明白的是File/@AssemblyApplication
属性的智能感知:
指定应用程序文件的标识符。该程序集将被隔离到与应用程序文件相同的目录中。如果此属性不存在,则程序集将安装到全局程序集缓存 (GAC)。
显然,我不希望我的应用程序安装到 GAC 中(而且,我认为它不应该是因为我设置File/@Assembly
为win32
)。问题是,属性值可以File/@AssemblyApplication
指向其父元素的@Id
属性吗?例如:
<Component Id="C__MyApp.exe" Guid="PUT-YOUR-GUID-HERE" DiskId="1">
<File Id="F__MyApp.exe" Vital="yes" KeyPath="yes"
Assembly="win32"
AssemblyManifest="F__MyApp.exe.manifest"
AssemblyApplication="F__MyApp.exe" />
<!-- @AssemblyApplication references it's parent element's @Id attribute. -->
<File Id="F__MyApp.exe.manifest" Vital="yes" KeyPath="no"
Name="MyApp.exe.manifest" Source="[to be filled in]" />
</Component>
这是Component
为包含应用程序清单的应用程序创作元素的正确方法吗?还是我应该忘记设置各种Assembly*
属性并创建两个Component
s,一个用于应用程序可执行文件,另一个用于其清单?