Зарегистрировать .NET COM DLL во время установки Wix

Фон:

Наше приложение является плагином для гораздо большего приложения. Все, что мы создаем, это DLL файлы, к которым подключается большее приложение. Из-за этого наш .NET (С#), DLL файлы должны быть зарегистрированы для COM-интерфейса.

У нас есть рабочий InstallShield проект, но по многим причинам, на которые я не буду входить, мы хотим его перенести WiX. Единственное, что нужно сделать для установщика, - это зарегистрировать наши DLL файлы для COM.

Проблемы

Вот пример компонента с одним DLL файлом.

<Component Id="MyComponent" Guid="COMPONENT-GUID" SharedDllRefCount="yes" >
    <File Id="MyDLL.dll" Name="MyDLL.dll" KeyPath="yes" Assembly=".net" 
          AssemblyManifest="MyDLL.dll" AssemblyApplication="MyDLL.dll" />
</Component>

В соответствии с принятым ответом Как зарегистрировать DLL файл Win32 COM в WiX 3?, рекомендуется добавить SelfRegCost=1 в тег File. Это приводит к ошибке во время установки:

Модуль C:\Program files\Product\MyDll.dll не удалось зарегистрировать. HRESULT -2147024769. Обратитесь к вашему персоналу службы поддержки.

Второй ответ в том же вопросе (Роб Меншинг) рекомендует против этого подхода, но добавить внутри тега файла:

<Class Id="PUT-CLSID-HERE" Context="InprocServer32" ThreadingModel="apartment" Description="Your server description">
        <ProgId Id="Your.Server.1" Description="Your ProgId description">
            <ProgId Id="Your.Server" Description="Your ProgId description" />
        </ProgId>
    </Class>

    <Class Id="PUT-PROXY-CLSID-HERE" Context="InprocServer32" ThreadingModel="both" Description="Your server Proxies, assuming you have them">
        <Interface Id="PUT-INTERFACEID-HERE" Name="IInterface1" />
        <Interface Id="PUT-INTERFACEID-HERE" Name="IInterface2" />
        <Interface Id="PUT-INTERFACEID-HERE" Name="IInterface3" />
        <Interface Id="PUT-INTERFACEID-HERE" Name="IInterface4" />
    </Class>

Я немного смущен, чтобы ввести идентификаторы CLSID. Я ввел сгенерированный GUID и установил его. Он был установлен отлично, но большее приложение не могло найти файлы DLL. (Я использовал теги интерфейса, созданные из heat.exe.)

Другой подход, найденный в том же вопросе (Адан Теген), рекомендует использовать   файл heat.exe myDll.dll -out my.wxs

Используя вывод, я добавляю его в тег File:

<TypeLib Id="Another Guid" Language="0" MagorVersion="1">
    <!--Interfaces generated from heat.exe-->
</TypeLib>

Каждый способ, с помощью которого я пытался зарегистрировать .NET для COM, потерпел неудачу, и, прочитав столько вопросов по теме, я не ближе к пониманию правильного пути ее выполнения. Что мне делать? Почему эта сложная задача, когда все остальное в WiX было довольно простым?

Следует отметить, что исходный проект InstallShield создал настраиваемое действие, которое вызывало бы regasm.exe. Если все остальное не удастся, это может быть возможно, но я предпочел бы сделать все правильно.

Я только что обнаружил, что heat.exe file myDll.dll -scom -o myDll.wxs выводит значения реестра, похожие на то, что мне нужно. Теперь, как мне ссылаться на вновь созданный компонент внутри DLL-компонента?

Ответ 1

Я только что обнаружил, что heat.exe file myDll.dll -scom -o myDll.wxs выводит значения реестра, похожие на то, что мне нужно.

Вы уверены в -scom там? AFAIK, этот вариант фактически подавляет регистрацию COM!

Теперь, как я могу ссылаться на вновь созданный компонент внутри DLL-компонента?

Компонент, сгенерированный heat.exe, уже включает элемент File для DLL. Таким образом, на самом деле он содержит все необходимое для установки и регистрации DLL файла. Вам не нужен оригинальный "компонент DLL".

Если вам нужно поместить файл и его регистрацию COM в отдельные компоненты, вам придется удалить элемент File из компонента, сгенерированного программой heat.exe.

Кроме того, компоненты не могут ссылаться на другие компоненты. У вас могут быть ссылки между ComponentGroup, хотя мы сильно используем нашу модель wixlibs для зависимостей, но это довольно продвинутый прецедент.