Похоже, что при регистрации библиотеки типов лучший способ - создать собственный файл IDL или ODL, который будет содержать ваши GUID. Библиотеки типов, сгенерированные непосредственно из сборки, [i] зависят [/ i] от номеров версий сборки: идентификаторы GUID генерируются на основе этой информации, даже если интерфейс не изменился. Visual Studio использует regasm для регистрации и создания библиотеки типов. Под этим он использует RegisterTypeLib, вызов win32. Использование элемента typelib, похоже, делает нечто подобное. Нет хорошо.
Тем не менее! Создание библиотеки типов вручную является болезненным. Можно получить эти GUID другим способом: выкопать их из библиотеки типов и создать элементы самостоятельно.
У Ларри Остермана есть необходимая информация: есть определенные ключи реестра, которые необходимо установить. Вы можете сделать это с помощью таблицы Registry (а в Wix3 это означает элементы RegistryValue). Хитрость здесь в том, чтобы получить GUID: любой старый GUID не будет работать. Обычно получение GUID - это просто поиск IDL для вашей библиотеки (вы написали свой собственный IDL, верно? :)).
Если вы не написали файл IDL или ODL для компиляции в библиотеку типов, они все еще существуют в этом файле. Microsoft предоставляет несколько удобных инструментов: LoadTypeLibEx и интерфейс ITypeLib. С помощью этих интерфейсов вы можете просматривать библиотеку типов и получать все виды информации. Как мы просматриваем библиотеку?
Я просто взглянул на то, как это сделал Регасм! Быстрая разборка позже, и мы находим, что regasm написан также на C #. День славы Я запустил проект, и с помощью нескольких операторов using и 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;
Уф. Итак, вы должны написать код для извлечения информации. Как только вы это сделаете, вы должны будете заполнить эту информацию в регистрационных записях, как указано Ларри Остерманом .
Конечно, вы можете избежать этого шага, просто написав свой собственный файл IDL для начала. Выбор за болью: решать только вам!