WiX:使用应用程序清单安装应用程序的组件规则

时间:2013-11-02 20:17:50

标签: wix windows-installer

我正在使用WiX 3.7编写安装程序。安装程序将安装一个旧的VB6程序(它是供应商专有的程序,我没有源代码)。因此,该程序使用了一些未安装最新版本Windows的旧COM库(例如Windows 7及更高版本 - 不确定Vista或XP)。

由于我最近了解到现在可以私下安装COM库而无需使用无注册表COM注册进行全局系统注册,这正是我打算为那些不再分发的COM库做的事情使用Windows操作系统。

为此,我创建了所需的清单文件,用于在应用程序加载和使用库时查找所有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,告诉操作系统该应用程序所依赖的程序集。所以我还创建了必需的清单文件。现在我需要创建用于部署应用程序及其清单的组件(或组件)。

根据File/@Assembly的VS intellisense:

  

指定此文件是否需要安装到全局程序集缓存(GAC)中的Win32程序集或.NET程序集。如果值为“.net”或“win32”,则此文件也必须是组件的关键路径。

然后,对于File/@AssemblyManifest

  

指定描述程序集的清单文件的文件标识符。清单应与其描述的程序集位于同一个组件中。仅当Assembly属性设置为“.net”或“win32”时才能指定此属性。

这一切都很好,而且我完全理解了这一切。因此,对于我在WiX中的应用程序File元素,到目前为止我已经这样做了:

<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,一个用于应用程序可执行文件,另一个用于其清单?

1 个答案:

答案 0 :(得分:0)

  

隔离的COM :您需要的是隔离的COM组件,这与Win32程序集( WinSxS < / strong>)和.NET   程序集( GAC )。

快速建议:

  

我的2分:Run this legacy application on a virtual machine instead!问题解决了吗?(可能已解决问题)。


  

警告:以下内容写得很匆忙。稍后再检查。

     

这个(古老的)真正的专家是Wim Coenen-不知道他不再潜入这个标签了:

     

并排 :这两种类型的程序集是并排安装的 win32文件 WinSxS < / strong>)或 .NET程序集并排安装( GAC )。因此,这意味着旧的Win32文件(本机代码)和现代的.NET程序集(托管代码-需要.NET运行时)。 Side-by-side obviously means that different versions of the same file (referred to as assembly) can co-exist and you can load the one you require by means of a manifest

隔离的COM :隔离的COM完全不同。 It is the installation and invocation of COM servers without any registry entanglements - all happening from within the same installation folder 。我经常将其称为“免注册COM”-也许是一个奇怪的术语。

  

这意味着您可以加载不兼容的COM服务器版本   从本地安装文件夹中获取任何二进制文件会消耗它们。   您需要做的就是将COM服务器及其清单转储到   本地安装文件夹。无需Win32或.NET程序集   安装。参见下面的现实检查...

  • 这“解决”了COM的一个巨大问题,即COM服务器的按机器注册或全局注册性质。换句话说,通常只安装一个版本的COM服务器(尽管从技术上来说,可以安装通常没有完成的不同版本的COM服务器-更改GUID和ID的噩梦)。
  • 它还有助于将您的应用程序与肮脏的软件包,安装程序,脚本和引发注册表中COM注册冲突的应用程序隔离。自COM到达以来,这一直是一个非常有问题的问题。

WiX标记 :只需将COM服务器和清单文件安装在同一文件夹中:

<Component>
  <File Source="mscomm32.ocx" />
  <File Source="mscomm32.sxs.manifest" />
</Component>
<Component>
  <File Source="threed32.ocx"  />
  <File Source="threed32.sxs.manifest" />
</Component>

真实性检查 :我的经验是,当您无法访问有问题的源代码时,很难使孤立的COM正常工作。原因是COM是二进制标准/二进制重用。据我了解,您需要与该隔离的COM完全相同的文件版本才能正常工作。 所有文件的版本正确。这并不是说人们没有成功使用该方法,而是我通常建议人们去虚拟化:依靠虚拟机来运行这些旧应用程序

我对这个旧答案有更多的了解:What do I do when launching an application triggers repeating, endless Windows Installer self-repair?(请参阅无注册COM部分)。