Поколение Typelib и установка с WiX

После выяснения о том, что Visual Studio делает для регистрации Библиотеки COM, стало ясно, что VS сделал две вещи для регистрации COM:

  1. Зарегистрированный библиотека COM
  2. Создает и регистрирует Библиотеку типов

Visual Studio, кажется, делает эту регистрацию с помощью regasm.exe. Для первой части (прямая регистрация COM) использование tallow или heat (WiX 2.0 или WiX 3.0), кажется, получает всю основную корректную информацию регистрации COM.

Однако то, что масло/тепло, кажется, не делает, настраивается установка библиотеки типов. Было бы возможно создать пользовательское действие, чтобы сделать, это с установщиком WiX и regasm.exe, но вызывающий пользовательские действия не является лучшими практиками когда дело доходит до Microsoft основанные на установщике установщики.

После дальнейшего исследования похоже, что msi имеет способность генерировать библиотеку типов на установку. На самом деле WiX, кажется, имеет прямую поддержку его! В элементе файла можно добавить элемент Typelib. На самом деле статья здесь о wix имеет пример заполнения элемента TypeLib с Интерфейсными элементами.

Кажется, что существует по крайней мере два необходимых атрибута к Интерфейсному элементу:

  1. Идентификатор
  2. Имя:

Larry Osterman говорит о других частях интерфейса, который должен быть зарегистрирован для TypeLib в целом, и эта Интерфейсная запись, кажется, заботится об отдельных частях. Larry говорит, что мы должны указать ProxyStubClassId32 как "{00020424-0000-0000-C000-000000000046}", таким образом, мы можем легко добавить это.

Тому, куда пойти оттуда и что заполнить для различных Интерфейсных элементов, озадачили меня. Я шел вперед и добавил элемент TypeLib к своему wix файлу, и он успешно компилирует. Я немного невежествен относительно того, как настроить Интерфейсные элементы все же. Что мы должны сделать для надлежащего заполнения элемента TypeLib, и какие приложения или инструменты я могу использовать для получения его?

Ответ ниже wcoenen выглядит многообещающим... Я собираюсь дать ему выстрел.

Обновление: Отправленный мое конечное решение ниже как ответ.

22
задан Community 23 May 2017 в 11:45
поделиться

3 ответа

Вот способ ленивого человека решить эту проблему: Используйте heat от WiX 3.0.

, Если Вам генерировали библиотеку типов автоматически и установленный через regasm, heat, может взять .tlb в качестве аргумента в

heat file c:\my\path\to\my.tlb -out tlb.wxs

, Это генерирует весь typelib и соединит интерфейсом с элементами, которые необходимо зарегистрировать. Это не решит проблему необходимости знать их заранее, и она не решит проблему изменения GUID, когда версия изменений блока (даже если интерфейс не сделает - который является единственным временем, Вы, как предполагается, изменяете ее), но это получит Вас отчасти там.

16
ответ дан 29 November 2019 в 05:26
поделиться

Следующий прием может помочь со сбором урожая любых изменений реестра и превращением их в wxs файл, включая typelib элемент, который Вы после.

  1. Первый, возвратите свой реестр в состоянии, где библиотека типов не была зарегистрирована:

    c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\regasm.exe /tlb /u mylib.dll
    
  2. Экспорт это чистое состояние реестра к hklm-before.reg:

    c:\WINDOWS\system32\reg.exe export HKLM hklm-before.reg
    
  3. Регистр библиотека типов снова:

    c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\regasm.exe /tlb mylib.dll
    
  4. Экспорт новое состояние реестра к hklm-after.reg:

    c:\WINDOWS\system32\reg.exe export HKLM hklm-after.reg
    
  5. Теперь у нас есть два текстовых файла, hklm-before.reg и hklm-after.reg. Создают файл diff.reg, который только содержит соответствующие различия между ними. Можно найти различия легко с diffing инструментом. Мне нравится использовать различный инструмент, включенный в TortoiseSVN, так как я уже использую это каждый день. (WinDiff, кажется, не работает хорошо в этом случае из-за кодирующих текст проблем.)

  6. Мы можем теперь преобразовать diff.reg в .wxs путем вызова heat.exe с эти reg команда. (Требует wix 3.5 или более новый.)

    heat reg diff.reg -out typelib.wxs
    
8
ответ дан 29 November 2019 в 05:26
поделиться

Это похоже для регистрации Библиотеки типов, лучший , путь состоял бы в том, чтобы генерировать собственный IDL или файл ODL, который будет содержать GUID. Typelib, сгенерированные непосредственно от блока, являются [я] зависимым [/i] на номерах версий блока: GUID сгенерированы на основе той информации, даже если интерфейс не изменился. Visual Studio использует regasm, чтобы зарегистрировать и генерировать typelib. Под этим это использует RegisterTypeLib, вызов win32. Используя typelib элемент, кажется, делает что-то подобное. Отрицательный результат.

Однако! Создание библиотеки типов вручную является болезненным. Возможно получить те GUID иначе: рытье их из typelib и создания элементов самостоятельно.

у Larry Osterman есть информация, это необходимо: существуют определенные ключи реестра, которые должны быть установлены. Можно сделать тех, которые имеют таблицу Registry (и в Wix3, который означает элементы RegistryValue.) Прием здесь получает GUID: любой старый GUID не будет работать. Обычно, получение GUID является просто вопросом взгляда в IDL для Вашей библиотеки (Вы записали свой собственный IDL, правильно?:)).

, Если Вы не записали IDL или файл ODL для компиляции в typelib, они все еще существуют в файле. Microsoft обеспечивает несколько удобных инструментов: LoadTypeLibEx и интерфейс ITypeLib. С этими интерфейсами можно просмотреть библиотеку типов и получить все виды информации. Как мы просматриваем библиотеку?

я просто смотрел на то, как Regasm сделал это! Быстрое демонтирует позже, и мы находим, что regasm записан в C# также. Славный день. Я запустил проект, и с несколькими операторами использования и PInvoke позже, мы имеем:

using System.Runtime.InteropServices;          // for struct marshaling 
using System.Runtime.InteropServices.ComTypes; // for the ITypeLib + related types

// TYPELIBATTR lives in two places: Interop and ComTypes, but the one
// in Interop is deprecated.
using TYPELIBATTR = System.Runtime.InteropServices.ComTypes.TYPELIBATTR; 

/// <summary>
/// The registry kind enumeration for LoadTypeLibEx.  This must be made
/// here, since it doesn't exist anywhere else in C# afaik.  This is found
/// here: http://msdn.microsoft.com/en-us/library/ms221159.aspx
/// </summary>
enum REGKIND
{
    REGKIND_DEFAULT,
    REGKIND_REGISTER,
    REGKIND_NONE
}

// and this is how we get the library.
[DllImport("oleaut32.dll", CharSet = CharSet.Unicode, PreserveSig = false)]
  private static extern void LoadTypeLibEx(string strTypeLibName, REGKIND regKind, out ITypeLib TypeLib);

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

ITypeLib lib = null;
LoadTypeLibEx(Value, REGKIND.REGKIND_NONE, out lib);
IntPtr libInfoPtr = IntPtr.Zero;
lib.GetLibAttr(out libInfoPtr);
TYPELIBATTR libInfo = 
    (TYPELIBATTR) Marshal.PtrToStructure(libInfoPtr, typeof(TYPELIBATTR));
int typeCount = lib.GetTypeInfoCount();
for (int i = 0; i < typeCount; ++i)
{
    ITypeInfo info;
    lib.GetTypeInfo(i, out info);
    IntPtr typeDescrPtr = IntPtr.Zero;
    info.GetTypeAttr(out typeDescrPtr);
    TYPELIBATTR type =
        (TYPELIBATTR)Marshal.PtrToStructure(typeDescrPtr, typeof(TYPELIBATTR));
    // get GUID, other info from the specific type
}

lib.ReleaseTLibAttr(libInfoPtr);
libInfoPtr = IntPtr.Zero;

Ух. Так, необходимо написать некоторый код для извлечения информации. Как только Вы делаете, необходимо заполнить ту информацию в Записи Registy, как определено Larry Osterman .

, Конечно, Вы могли избежать что шаг путем простой записи собственного файла IDL для начала. Выбор в боли: Вам решать!

3
ответ дан 29 November 2019 в 05:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: