如何让我的 WiX 产品脚本正确安装我的 active x 控件?

How can I get my WiX product script to correctly install my active x control?

情况 我已经编写了一个自定义 Active X 控件,用于在另一个非 Web 应用程序中使用。当我手动 运行 "regasm /codebase MyMacTest.dll" 控件已注册并且可以使用 jscript 解释器在应用程序中使用它。这意味着我需要创建一个 ActiveXObject 等...。

所以我的下一步是使用 Wix 工具集 3.11 创建安装 MSI。根据我读到的内容,我需要 运行 Heat 对抗 dll 来创建输出 wxs 内容。我这样做并将其添加到我的 product.wxs 编译和 运行 中。它正确部署了我的 dll,验证了注册表项,但它在应用程序中不起作用。

我的 C# 代码:

using System;
using System.Runtime.InteropServices;

namespace MyMacTest
{
    [ProgId("MyMacTest.MacroTest")]
    [ClassInterface(ClassInterfaceType.None)]
    [Guid("765563f5-55b0-41e1-9f49-311ec88f6ba2")]
    [ComVisible(true)]
    public class MacroTest
    {
        public MacroTest()
        {

        }

        public string GetMessage()
        {
            return $"This is a test for {DateTime.Now}";
        }
    }
 }

已编译 DLL 的 Heat 输出:

<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
    <DirectoryRef Id="TARGETDIR">
        <Directory Id="dir39B22699688E51DCD8DCBB99A47E835B" Name="Debug" />
    </DirectoryRef>
</Fragment>
<Fragment>
    <DirectoryRef Id="dir39B22699688E51DCD8DCBB99A47E835B">
        <Component Id="cmp88AF0B935698304B52D96A0CEA4F7661" Guid="PUT-GUID-HERE">
            <Class Id="{765563F5-55B0-41E1-9F49-311EC88F6BA2}" Context="InprocServer32" Description="MyMacTest.MacroTest" ThreadingModel="both" ForeignServer="mscoree.dll">
                <ProgId Id="MyMacTest.MacroTest" Description="MyMacTest.MacroTest" />
            </Class>
            <File Id="filC0F476996EBA80AC7C8F27AA886F48E0" KeyPath="yes" Source="SourceDir\Debug\MyMacTest.dll" />
            <RegistryValue Root="HKCR" Key="CLSID\{765563F5-55B0-41E1-9F49-311EC88F6BA2}\Implemented Categories\{62C8FE65-4EBB-45e7-B440-6E39B2CDBF29}" Value="" Type="string" Action="write" />
            <RegistryValue Root="HKCR" Key="CLSID\{765563F5-55B0-41E1-9F49-311EC88F6BA2}\InprocServer32.0.0.0" Name="Class" Value="MyMacTest.MacroTest" Type="string" Action="write" />
            <RegistryValue Root="HKCR" Key="CLSID\{765563F5-55B0-41E1-9F49-311EC88F6BA2}\InprocServer32.0.0.0" Name="Assembly" Value="MyMacTest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=583df5a1a2a0a8da" Type="string" Action="write" />
            <RegistryValue Root="HKCR" Key="CLSID\{765563F5-55B0-41E1-9F49-311EC88F6BA2}\InprocServer32.0.0.0" Name="RuntimeVersion" Value="v4.0.30319" Type="string" Action="write" />
            <RegistryValue Root="HKCR" Key="CLSID\{765563F5-55B0-41E1-9F49-311EC88F6BA2}\InprocServer32.0.0.0" Name="CodeBase" Value="file:///[#filC0F476996EBA80AC7C8F27AA886F48E0]" Type="string" Action="write" />
            <RegistryValue Root="HKCR" Key="CLSID\{765563F5-55B0-41E1-9F49-311EC88F6BA2}\InprocServer32" Name="Class" Value="MyMacTest.MacroTest" Type="string" Action="write" />
            <RegistryValue Root="HKCR" Key="CLSID\{765563F5-55B0-41E1-9F49-311EC88F6BA2}\InprocServer32" Name="Assembly" Value="MyMacTest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=583df5a1a2a0a8da" Type="string" Action="write" />
            <RegistryValue Root="HKCR" Key="CLSID\{765563F5-55B0-41E1-9F49-311EC88F6BA2}\InprocServer32" Name="RuntimeVersion" Value="v4.0.30319" Type="string" Action="write" />
            <RegistryValue Root="HKCR" Key="CLSID\{765563F5-55B0-41E1-9F49-311EC88F6BA2}\InprocServer32" Name="CodeBase" Value="file:///[#filC0F476996EBA80AC7C8F27AA886F48E0]" Type="string" Action="write" />
        </Component>
    </DirectoryRef>
</Fragment>

我用热片段修改的产品:

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"><?define MyMacTest_TargetDir=$(var.MyMacTest.TargetDir)?>
<Product Id="*" Name="MyMacSetup" 
       Language="1033" 
       Version="1.0.0.0" 
       Manufacturer="Mega Software Stuff" 
       UpgradeCode="b3e8921b-22da-4f05-a79f-36cafde09fce">
    <Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />

    <MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
    <MediaTemplate EmbedCab="yes"/>

    <Feature Id="ProductFeature" Title="MyMacSetup" Level="1">
        <ComponentGroupRef Id="ProductComponents" />
  <ComponentRef Id="cmp88AF0B935698304B52D96A0CEA4F7661"/>
    </Feature>
</Product>

<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
  <Directory Id="ProgramFilesFolder">
    <Directory Id="Bp" Name="BPE">
      <Directory Id="Addin" Name="AddIns">
        <Directory Id="INSTALLFOLDER" Name="MyCustom" />
      </Directory>
    </Directory>
  </Directory>
</Directory>
</Fragment>

<Fragment>
    <ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
        <Component Id="MyMacTest.dll" Guid="21b3cee3-1da3-4f48-89db-7c2f6cf11431">
          <File Id="MyMacTest.dll" Name="MyMacTest.dll" Source="$(var.MyMacTest_TargetDir)MyMacTest.dll" />
        </Component>
    </ComponentGroup>
</Fragment>

<!-- This segment gotten from heat: "c:\Program Files (x86)\WiX Toolset v3.11\bin\heat" file MyMacTest.dll -out mymactest.wxs  -->
<Fragment>
<DirectoryRef Id="INSTALLFOLDER">
  <Component Id="cmp88AF0B935698304B52D96A0CEA4F7661" Guid="b33671b4-2f75-44bc-8435-f16c5f9b7268">
    <Class Id="{765563F5-55B0-41E1-9F49-311EC88F6BA2}" Context="InprocServer32" Description="MyMacTest.MacroTest" ThreadingModel="both" ForeignServer="mscoree.dll">
      <ProgId Id="MyMacTest.MacroTest" Description="MyMacTest.MacroTest" />
    </Class>
    <!--<File Id="filC0F476996EBA80AC7C8F27AA886F48E0" KeyPath="yes" Source="$(var.MyMacTest_TargetDir)MyMacTest.dll" />-->
    <RegistryValue Root="HKCR" Key="CLSID\{765563F5-55B0-41E1-9F49-311EC88F6BA2}\Implemented Categories\{62C8FE65-4EBB-45e7-B440-6E39B2CDBF29}" Value="" Type="string" Action="write" />
    <RegistryValue Root="HKCR" Key="CLSID\{765563F5-55B0-41E1-9F49-311EC88F6BA2}\InprocServer32.0.0.0" Name="Class" Value="MyMacTest.MacroTest" Type="string" Action="write" />
    <RegistryValue Root="HKCR" Key="CLSID\{765563F5-55B0-41E1-9F49-311EC88F6BA2}\InprocServer32.0.0.0" Name="Assembly" Value="MyMacTest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=583df5a1a2a0a8da" Type="string" Action="write" />
    <RegistryValue Root="HKCR" Key="CLSID\{765563F5-55B0-41E1-9F49-311EC88F6BA2}\InprocServer32.0.0.0" Name="RuntimeVersion" Value="v4.0.30319" Type="string" Action="write" />
    <RegistryValue Root="HKCR" Key="CLSID\{765563F5-55B0-41E1-9F49-311EC88F6BA2}\InprocServer32.0.0.0" Name="CodeBase" Value="file:///[#MyMacTest.dll]" Type="string" Action="write" />
    <RegistryValue Root="HKCR" Key="CLSID\{765563F5-55B0-41E1-9F49-311EC88F6BA2}\InprocServer32" Name="Class" Value="MyMacTest.MacroTest" Type="string" Action="write" />
    <RegistryValue Root="HKCR" Key="CLSID\{765563F5-55B0-41E1-9F49-311EC88F6BA2}\InprocServer32" Name="Assembly" Value="MyMacTest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=583df5a1a2a0a8da" Type="string" Action="write" />
    <RegistryValue Root="HKCR" Key="CLSID\{765563F5-55B0-41E1-9F49-311EC88F6BA2}\InprocServer32" Name="RuntimeVersion" Value="v4.0.30319" Type="string" Action="write" />
    <RegistryValue Root="HKCR" Key="CLSID\{765563F5-55B0-41E1-9F49-311EC88F6BA2}\InprocServer32" Name="CodeBase" Value="file:///[#MyMacTest.dll]" Type="string" Action="write" />
  </Component>
</DirectoryRef>
</Fragment>
</Wix>

我的问题是:

花了几天时间后,我发现似乎有很多关于此的消息,但没有任何内容给我提供逐步示例或解释如何创建将执行 "regasm /codebase" 我需要做的。有点混乱。这是我的第一个 wix/MSI 项目。

我错过了什么 and/or 我需要知道什么才能完成这项工作?有什么地方有好的一步一步的,我还没有找到,我可以指出吗?

更新差异

使用 regasm /codebase 手动注册

[HKEY_CLASSES_ROOT\CLSID\{765563F5-55B0-41E1-9F49-311EC88F6BA2}]
@="MyMacTest.MacroTest"

[HKEY_CLASSES_ROOT\CLSID\{765563F5-55B0-41E1-9F49-311EC88F6BA2}\Implemented Categories]

[HKEY_CLASSES_ROOT\CLSID\{765563F5-55B0-41E1-9F49-311EC88F6BA2}\Implemented Categories\{62C8FE65-4EBB-45e7-B440-6E39B2CDBF29}]

[HKEY_CLASSES_ROOT\CLSID\{765563F5-55B0-41E1-9F49-311EC88F6BA2}\InprocServer32]
@="mscoree.dll"
"ThreadingModel"="Both"
"Class"="MyMacTest.MacroTest"
"Assembly"="MyMacTest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=583df5a1a2a0a8da"
"RuntimeVersion"="v4.0.30319"
"CodeBase"="file:///C:/Users/Kevin/OneDrive/Documents/MyMacTest.DLL"

[HKEY_CLASSES_ROOT\CLSID\{765563F5-55B0-41E1-9F49-311EC88F6BA2}\InprocServer32.0.0.0]
"Class"="MyMacTest.MacroTest"
"Assembly"="MyMacTest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=583df5a1a2a0a8da"
"RuntimeVersion"="v4.0.30319"
"CodeBase"="file:///C:/Users/Kevin/OneDrive/Documents/MyMacTest.DLL"

[HKEY_CLASSES_ROOT\CLSID\{765563F5-55B0-41E1-9F49-311EC88F6BA2}\ProgId]
@="MyMacTest.MacroTest"

===========================================

微星安装

[HKEY_CLASSES_ROOT\WOW6432Node\CLSID\{765563F5-55B0-41E1-9F49-311EC88F6BA2}]
 @="MyMacTest.MacroTest"

[HKEY_CLASSES_ROOT\WOW6432Node\CLSID\{765563F5-55B0-41E1-9F49-311EC88F6BA2}\Implemented Categories]

[HKEY_CLASSES_ROOT\WOW6432Node\CLSID\{765563F5-55B0-41E1-9F49-311EC88F6BA2}\Implemented Categories\{62C8FE65-4EBB-45e7-B440-6E39B2CDBF29}]
@=""

[HKEY_CLASSES_ROOT\WOW6432Node\CLSID\{765563F5-55B0-41E1-9F49-311EC88F6BA2}\InprocServer32]
@="mscoree.dll"
"ThreadingModel"="Both"
"Class"="MyMacTest.MacroTest"
"Assembly"="MyMacTest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=583df5a1a2a0a8da"
"RuntimeVersion"="v4.0.30319"
"CodeBase"="file:///C:\Program Files (x86)\BPE\AddIns\MyCustom\MyMacTest.dll"

[HKEY_CLASSES_ROOT\WOW6432Node\CLSID\{765563F5-55B0-41E1-9F49-311EC88F6BA2}\InprocServer32.0.0.0]
"Class"="MyMacTest.MacroTest"
"Assembly"="MyMacTest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=583df5a1a2a0a8da"
"RuntimeVersion"="v4.0.30319"
"CodeBase"="file:///C:\Program Files (x86)\BPE\AddIns\MyCustom\MyMacTest.dll"

[HKEY_CLASSES_ROOT\WOW6432Node\CLSID\{765563F5-55B0-41E1-9F49-311EC88F6BA2}\ProgID]
@="MyMacTest.MacroTest"

不确定为什么 MSI 安装将 WOW6432Node 添加到路径中...但这些是不同之处。

谢谢!

更新:请注意 COM 是位感知的。在您的示例中,您正在构建一个 32 位 MSI,它将在 32 位注册表中安装 COM 服务器。您可能正在从 64 位进程调用它,但那是行不通的。

您的做法大体上可行。要排除故障,您需要:

1) 创建 VM 并为其创建快照

2) 安装 MSI

3) 运行 注册表差异工具,例如 Install Watch Pro 或 InControl。拍摄注册表快照。

4) 从提升的命令提示符手动 运行 你的 regasm /codebase 命令。

5) 拍摄另一个注册表快照和 运行 差异报告。

6) 检查有意义的相关差异的差异,并将它们编写到您的 WXS 源代码中。

7) 重建 MSI

8) 应用 VM 快照以恢复到干净状态。

9) 安装 MSI 并重新测试功能。

如果您想知道为什么热量不能单独工作,那么答案与 COM 有关。有时嗅探技术根本不起作用。对于 .NET COM Interop / COM Visible 程序集,有时答案就在于此警告。在您的情况下,这可能与您对 ClassInterface 属性的使用有关。

https://docs.microsoft.com/en-us/dotnet/framework/tools/regasm-exe-assembly-registration-tool

You can use the /regfile option to generate a .reg file that contains the registry entries instead of making the changes directly to the registry. You can update the registry on a computer by importing the .reg file with the Registry Editor tool (Regedit.exe). Note that the .reg file does not contain any registry updates that can be made by user-defined register functions. Note that the /regfile option only emits registry entries for managed classes. This option does not emit entries for TypeLibIDs or InterfaceIDs.

如果您无法解决这个问题,我有 25 年处理此类问题的经验。如果您能够共享 DLL 并给我一个代码片段来进行冒烟测试,我可以创建一个正确注册程序集的 WiX 片段。

PS- 我会合并这两个组件。 COM/Registry 元素应该与它们所在的文件属于同一组件。