com - 在 64 位组件中注册 32 位 COM 类

标签 com wix windows-installer 32bit-64bit

我使用 SharpShell 为 Windows Explorer shell 构建了一个 ContextMenuHandler 。该程序集是为 AnyCPU 构建的,即在 MSIL 中,因此可以作为 32 位和 64 位运行。

我打算只在 64 位 Windows 上运行它,但是,Windows 64 上的 32 位应用程序仍然使用 32 位版本的 shell 来打开对话框等。

我已在两种体系结构(32 和 64)上使用 regasm 工具手动注册了该程序集,并且它在 64 位 Windows 资源管理器中运行良好。它也可以在 32 位应用程序中通过文件打开和其他 shell 提供的对话框运行。这是预期的行为,太棒了!

我遇到的问题是编写安装脚本,我使用的是Wix 3.7,我不想使用regasm。

64 位组件安装有:-

<Component Id="cmpMyAssembly64" Directory="INSTALL_TO_HERE"
    Location="local" Win64="yes">
  <File Id="filMyAssembly" KeyPath="yes" Source="mySource.dll"
      Assembly=".net" AssemblyApplication="filMyAssembly"
      ProcessorArchitecture="msil"/>

  <Class Id="01201201-0000-0000-0000-012345670123" Description="My Handler"
         Context="InprocServer32" ThreadingModel="both" ForeignServer="mscoree.dll">
    <ProgId Id="A.ContextHandler" Description="Does something" />
  </Class>

  <RegistryKey Root="HKCR" Key="CLSID\{01201201-0000-0000-0000-012345670123}"
      ForceCreateOnInstall="yes" ForceDeleteOnUninstall="yes">
    <RegistryKey Key="Implemented Categories\{62C8FE65-4EBB-45e7-B440-6E39B2CDBF29}">
      <RegistryValue Value="" Type="string" />
    </RegistryKey>

    <RegistryKey Key="InprocServer32">
      <RegistryKey Key="1.0.0.0">
        <RegistryValue Name="Class" Value="aNamespace.theClass" Type="string" />
        <RegistryValue Name="Assembly" Value="!(bind.assemblyFullName.filMyAssembly)" Type="string" />
        <RegistryValue Name="RuntimeVersion" Value="v4.0.30319" Type="string" />
        <RegistryValue Name="CodeBase" Value="file:///[#filMyAssembly]" Type="string" />
      </RegistryKey>

        <RegistryValue Name="Class" Value="aNamespace.theClass" Type="string" />
        <RegistryValue Name="Assembly" Value="!(bind.assemblyFullName.filMyAssembly)" Type="string" />
        <RegistryValue Name="RuntimeVersion" Value="v4.0.30319" Type="string" />
        <RegistryValue Name="CodeBase" Value="file:///[#filMyAssembly]" Type="string" />
    </RegistryKey>
  </RegistryKey>

  <RegistryValue Root="HKCR" Key="Directory\Background\shellex\ContextMenuHandlers\MyHandler" Value="{guid}" Type="string" Action="write" />
  <RegistryValue Root="HKCR" Key="Directory\shellex\ContextMenuHandlers\MyHandler" Value="{guid}" Type="string" Action="write" />
  <RegistryValue Root="HKCR" Key="Drive\shellex\ContextMenuHandlers\MyHandler" Value="{guid}" Type="string" Action="write" />
</Component>

我遇到的问题是 32 位版本的注册。因为它使用相同的程序集,所以我不想安装相同的文件两次。我所做的就是创建另一个(32 位)组件并进行必要的注册表更改。

<Component Id="cmp32BitVersion" Directory="INSTALL_TO_32"
    Location="local" Win64="no">
  <Class ... just like 64bit
  <RegistryKey ... just like 64bit
</Component>

现在,我假设 Win64 是/否是 Windows 安装程序决定写入注册表的哪一部分的方式。对于 64 位组件,它会写入 HKCR...,对于 32 位组件,它会写入 HKLM\SOFTWARE\WOW6432Node\Classes。我遇到的问题是,因为两个组件都使用文件引用 [#filMyAssembly],我收到 ICE69:组件引用不匹配的警告。代码仍然可以构建,但我不想收到警告,不注意警告的人应该会遇到麻烦。

无论如何,我的问题是:使用 Wix/Windows Installer 在 64 位和 32 位应用程序中为 COM 注册 MSIL 程序集的正确方法是什么?

最佳答案

wix-users 的 MikeR 和 nickheppleston 看起来已经找到了解决方案:

http://windows-installer-xml-wix-toolset.687559.n2.nabble.com/64-bit-and-32-bit-Registry-Keys-in-same-MSI-td4439679.html

Thanks all who have responded. I followed MikeR's comments and came up with the following - I found that I had to reference the x64 Architecture variable when defining both the Component and the ComponentRef within the Feature section, as follows:

<Component Id="x86LicencingRegistryKeys" Guid="D113AD25-9E80-44E9-80C0-D66828809DBF" Win64="no">


        <RegistryKey Id="x86ValidationCodeRegKey" Root="HKLM" Key="SOFTWARE\Product\Licencing" Action="createAndRemoveOnUninstall">
                <RegistryValue Id="x86ValidationCodeRegValue" Name="ValidationCode" Action="write" Value="BgIAAACkAABSU0ExgAEAAAEAAQD9iAIysvGIxaJcIiENpOVTZbQosafHa9yXlfG0kxSWKJ01Hlfl+I+4ul5LhxoZkLo=" Type="string" />
                <Permission User="Administrators" ChangePermission="yes" GenericAll="yes" />
                <Permission User="CREATOR OWNER" ChangePermission="yes" GenericAll="yes" />
                <Permission User="Power Users" ChangePermission="yes" GenericAll="yes" />
                <Permission User="SYSTEM" ChangePermission="yes" GenericAll="yes" />
                <Permission User="Users" ChangePermission="yes" GenericAll="no" GenericRead="yes" />
        </RegistryKey>



        <RegistryKey Id="x86LicenceKeyRegKey" Root="HKLM" Key="SOFTWARE\Product\Licencing" Action="createAndRemoveOnUninstall">
                <RegistryValue Id="x86LicenceKeyRegValue" Name="LicenceKey" Action="write" Value="" Type="string" />
                <Permission User="Administrators" ChangePermission="yes" GenericAll="yes" />
                <Permission User="CREATOR OWNER" ChangePermission="yes" GenericAll="yes" />
                <Permission User="Power Users" ChangePermission="yes" GenericAll="yes" />
                <Permission User="SYSTEM" ChangePermission="yes" GenericAll="yes" />
                <Permission User="Users" ChangePermission="yes" GenericAll="no" GenericRead="yes" />                               
        </RegistryKey>


</Component>


<?if $(var.Architecture)=x64 ?>

<Component Id="x64LicencingRegistryKeys" Guid="49A15EB4-2DF8-4FF9-83ED-D306F076E232" Win64="yes">


        <RegistryKey Id="x64ValidationCodeRegKey" Root="HKLM" Key="SOFTWARE\Product\Licencing" Action="createAndRemoveOnUninstall">
                <RegistryValue Id="x64ValidationCodeRegValue" Name="ValidationCode" Action="write" Value="BgIAAACkAABSU0ExgAEAAAEAAQD9iAIysvGIxaJcIiENpOVTZbQosafHa9yXlfG0kxSWKJ01Hlfl+I+4ul5LhxoZkLo=" Type="string" />
                <Permission User="Administrators" ChangePermission="yes" GenericAll="yes" />
                <Permission User="CREATOR OWNER" ChangePermission="yes" GenericAll="yes" />
                <Permission User="Power Users" ChangePermission="yes" GenericAll="yes" />
                <Permission User="SYSTEM" ChangePermission="yes" GenericAll="yes" />
                <Permission User="Users" ChangePermission="yes" GenericAll="no" GenericRead="yes" />
        </RegistryKey>



        <RegistryKey Id="x64LicenceKeyRegKey" Root="HKLM" Key="SOFTWARE\Product\Licencing" Action="createAndRemoveOnUninstall">
                <RegistryValue Id="x64LicenceKeyRegValue" Name="LicenceKey" Action="write" Value="" Type="string" />
                <Permission User="Administrators" ChangePermission="yes" GenericAll="yes" />
                <Permission User="CREATOR OWNER" ChangePermission="yes" GenericAll="yes" />
                <Permission User="Power Users" ChangePermission="yes" GenericAll="yes" />
                <Permission User="SYSTEM" ChangePermission="yes" GenericAll="yes" />
                <Permission User="Users" ChangePermission="yes" GenericAll="no" GenericRead="yes" />                               
        </RegistryKey>


</Component>

<?endif ?>


<Feature Id="Complete" Title="TITLE" Description="Complete Package" Display="expand" Level="1" ConfigurableDirectory="INSTALLDIR">
<ComponentRef Id="x86LicencingRegistryKeys" /> 
<?if $(var.Architecture)=x64 ?><ComponentRef Id="x64LicencingRegistryKeys" /><?endif ?> 
</Feature>

关于com - 在 64 位组件中注册 32 位 COM 类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19828050/

相关文章:

c++ - 为什么我的 dll 中的类型库损坏(注册返回 TYPE_E_CANTLOADLIBRARY)?

winapi - Direct3D 中的 COM 对象

user-interface - WiX 编译错误创建自定义对话框

wix - 使用 WiX/Burn 安装后启动应用程序

c# - 从 .msi 读取平台信息

javascript - Extjs 组合在 IE7 中不起作用

c++ - IXSomething 与 ISomething

java - 在 wxi 和 wxs 中使用具有相同 Id 的 WIX 功能元素

WiX:构建服务器构建中神秘且难以诊断的 ICE 验证错误

wix - 将条目添加到 MSI UpgradeTable 以删除相关产品