如何构建Wix安装程序升级以将GAC组件移动到常规文件夹中



我有一个现有的安装,其中包括为COM互操作注册并安装在GAC中的. net程序集。这些dll仅由我们在安装中包含的非托管EXE使用。

一个简单的示例组件(与实际组件混淆)看起来像这样:

  <Component Id="MyApp.ClientInterop.dll" Guid="{9A9C2B62-531C-4E60-ABD2-EDD447643C4F}">
    <Class Id="{963057C7-83B4-4602-87B4-B0AB9D3D149A}" Context="InprocServer32" Description="MyApp.ClientInterop.ClientAppUpdate" ThreadingModel="both" ForeignServer="mscoree.dll">
      <ProgId Id="MyApp_Interop.ClientAppUpdate" Description="MyApp.ClientInterop.ClientAppUpdate" />
    </Class>
    <File Id="MyApp.ClientInterop.dll" Name="MyApp.ClientInterop.dll" KeyPath="yes" Assembly=".net">
      <TypeLib Id="{08963623-70A8-4DD8-A8DA-EAF209919797}" Description="MyApp_ClientInterop" Language="0" MajorVersion="1" MinorVersion="0">
        <Interface Id="{207BB6C4-3054-4853-BA20-40D99EA6ACFE}" Name="IClientAppUpdate" ProxyStubClassId="{00020424-0000-0000-C000-000000000046}" ProxyStubClassId32="{00020424-0000-0000-C000-000000000046}" />
      </TypeLib>
    </File>
    <RegistryValue Root="HKCR" Key="CLSID{963057C7-83B4-4602-87B4-B0AB9D3D149A}Implemented Categories{62C8FE65-4EBB-45e7-B440-6E39B2CDBF29}" Value="" Type="string" Action="write" />
    <RegistryValue Root="HKCR" Key="CLSID{963057C7-83B4-4602-87B4-B0AB9D3D149A}InprocServer321.0.0.0" Name="Class" Value="MyApp.ClientInterop.ClientAppUpdate" Type="string" Action="write" />
    <RegistryValue Root="HKCR" Key="CLSID{963057C7-83B4-4602-87B4-B0AB9D3D149A}InprocServer321.0.0.0" Name="Assembly" Value="MyApp.ClientInterop, Version=1.0.0.0, Culture=neutral, PublicKeyToken=cf47a01d50a7b0f5" Type="string" Action="write" />
    <RegistryValue Root="HKCR" Key="CLSID{963057C7-83B4-4602-87B4-B0AB9D3D149A}InprocServer321.0.0.0" Name="RuntimeVersion" Value="v4.0.30319" Type="string" Action="write" />
    <RegistryValue Root="HKCR" Key="CLSID{963057C7-83B4-4602-87B4-B0AB9D3D149A}InprocServer32" Name="Class" Value="MyApp.ClientInterop.ClientAppUpdate" Type="string" Action="write" />
    <RegistryValue Root="HKCR" Key="CLSID{963057C7-83B4-4602-87B4-B0AB9D3D149A}InprocServer32" Name="Assembly" Value="MyApp.ClientInterop, Version=1.0.0.0, Culture=neutral, PublicKeyToken=cf47a01d50a7b0f5" Type="string" Action="write" />
    <RegistryValue Root="HKCR" Key="CLSID{963057C7-83B4-4602-87B4-B0AB9D3D149A}InprocServer32" Name="RuntimeVersion" Value="v4.0.30319" Type="string" Action="write" />
  </Component>

由于一些原因,我不会在这里深入讨论,我们希望重新构建应用程序,使dll与可执行文件一起存在于文件夹中,而不是在GAC中。

这可以通过主要升级来完成,而不需要用户完全卸载以前的版本吗?我们的安装程序是有序的,所以旧版本在最终完成时被删除,因为大多数升级只改变了一小部分组件。

我最初计划对每个GAC组件进行以下更改:

  1. 删除组装= "。属性
  2. 在Component元素上生成新的Guid

这对于文件系统应该是有效的。但是,我不确定,,,,和元素会发生什么。如果我不更改这些,我怀疑它们将在最后旧版本卸载时被删除,留下一个损坏的安装。

这是准确的解释吗?这是否意味着我需要为所有的互操作类强制使用新的Interface/Typelib/CLSID值?在这个项目上,我有超过1000个类通过互操作暴露。

我可以改变顺序,先安装旧的产品吗?我很关心这样做,因为这意味着我必须保持这个顺序,直到我可以确定我的所有客户都超出了那个版本。它还将显著增加安装时间(之前已经测试过)。

也许还有另一个我不知道的选择?

在开始时使用RemoveExistingProducts进行主要升级会更安全,可以说是一个干净的石板。然而,我认为它将与REP在最后工作,如果:

  1. 您的组件获得一个新的组件指南,以便从GAC中删除旧的产品组件。

  2. 注册表项没有版本控制,因此它们总是被覆盖。您应该能够保持相同的WiX组件id,但无论如何您都需要添加CodeBase位置,因此应该很容易看到它是否全部工作。显然,在升级之后,您不需要GAC中的程序集,普通文件系统中的程序集,指向它们的CodeBase注册表项,以及可以调用它们的客户端ok:)

最新更新