Отладка COM бесплатная регистрация (C++)

Я создал клиентское приложение COM, которое использует две библиотеки COM-сервера; Я хочу, чтобы это приложение запускалось без регистрации COM - то есть: winsxs / .manifests

Я получаю (... почти ожидаемое...) сообщение "Класс не зарегистрирован", когда я пытаюсь создать экземпляр моего COM-объекта из моего клиентского приложения.

Я уже преуспел в такой конфигурации раньше, но я не могу понять, почему эта неудача.


вот еще несколько деталей:

  • модули у меня есть:
    • клиент MFC, который зависит от 2 COM-серверов (dll1.dll и dll2.dll)
    • COM-сервер dll1.dll зависит от dll2.dll
    • У dll2.dll нет COM-зависимости

COM-объекты у меня есть:

  • в dll1.dll (язык.idl)

-

[
    object,
    uuid(262D00FB-3B9F-4A76-98FC-3051FDCAF0A6),
    dual,
    nonextensible,
    helpstring("IDialogManager Interface"),
    pointer_default(unique)
]
interface IDialogManager : IDispatch{
};
[
        uuid(58562535-BCA5-4D04-BB92-78F90EDA201E),
        //...
]
dispinterface _IDialogManagerEvents
{
};
[
        uuid(D599D3F0-A4D1-44A7-87A9-16032CC613CA),
        //...
]
coclass DialogManager
{
        [default] interface IDialogManager;
        [default, source] dispinterface _IDialogManagerEvents;
};

-

  • в dll2.dll

-

[
    object,
    uuid(2A183A2E-A620-4E00-B657-C9D2E59201D4),
    nonextensible,
    helpstring("ICadWizardsManager Interface"),
    pointer_default(unique)
]
interface ICadWizardsManager : IDispatch{
};
[
    object,
    uuid(FE97F3FB-8930-43BC-947D-64C90F45A071),
    nonextensible,
    helpstring("ICadWizard Interface"),
    pointer_default(unique)
]
interface ICadWizard : IDispatch{
};
[
    uuid(5365D4E6-ADFB-4429-9DEA-C44CC94AA3EF),
]
dispinterface _ICadWizardEvents
{
};
[
    uuid(CAC2D0BF-AD5B-4CC8-A04D-53AB23A0CDF4),
]
coclass CadWizard
{
    [default] interface ICadWizard;
    [default, source] dispinterface _ICadWizardEvents;
};
[
    uuid(3164FAC4-6F5F-4E4D-9B09-DC4115850D78),
]
dispinterface _ICadWizardsManagerEvents
{
};
[
    uuid(707CB6C8-311E-45EC-9DCB-50477F588BAF),
]
coclass CadWizardsManager
{
    [default] interface ICadWizardsManager;
    [default, source] dispinterface _ICadWizardsManagerEvents;
};

-

  • звонок клиента

-

IDialogManagerPtr dialogManager;
dialogManager.CreateInstance(CLSID_DialogManager); // <<< returns "Class not registered"

-

  • client.exe.2.manifest

-

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

<assemblyIdentity name="client" version="1.0.0.0" type="win32" processorArchitecture="x86"/>
<file name="dll2.dll">
 <comClass
     clsid="{707CB6C8-311E-45EC-9DCB-50477F588BAF}"
     threadingModel="apartment">
 </comClass>
 <comClass
     clsid="{CAC2D0BF-AD5B-4CC8-A04D-53AB23A0CDF4}"
     threadingModel="apartment">
 </comClass>
</file>

<file name="dll1.dll">
 <comClass
     clsid="{D599D3F0-A4D1-44A7-87A9-16032CC613CA}"
     threadingModel="apartment">
 </comClass>
</file>

</assembly>

-


У меня нет ошибок во время генерации контекста активации sxs: - нет ошибки в журнале Windows (должно означать, что мой синтаксис манифеста правильный) - sxstrace не обнаружил ошибки (журнал заканчивается сообщением "INFO: Генерация контекста активации успешно завершена". ошибка или подозрительное сообщение, более того, я вижу, что мой манифест загружен правильно)

Любая идея?

Есть ли способ отладить SXS глубже, чем с SXSTRACE? например, получить список реально зарегистрированных классов com или clr???

Заранее спасибо

2 ответа

Решение

Обычно при создании контекста активации для свободной COM-регистрации участвуют, как минимум, два манифеста.

Существует манифест EXE, который определяет его зависимые сборки, включая сборку, содержащую компоненты COM, и манифест сборки, описывающий библиотеки DLL, классы окон и COM-объекты в сборке.

Этот блог содержит информацию о том, что означает.2. По сути, когда система ищет манифест, она ищет modulename.exe [.resid].manifest - в случае, если остаток равен 1, он опускается.

Итак, вы используете MFC, что означает DevStudio, что означает, что ваш проект уже должен быть настроен на автоматическое создание ресурса RT_MANIFEST с настройками c-runtime и common control 6.

Visual Studio 2005 поддерживает этот синтаксис для объединения элементов зависимых сборок с манифестом ваших приложений без необходимости непосредственно пытаться объединить XML:

#pragma comment(linker, \
    "\"/manifestdependency:type='Win32' "\
    "name='client' "\
    "version='1.0.0.0' "\
    "processorArchitecture='*' "\
    "language='*'\"")

Таким образом, если вы добавите это в cpp или заголовок в вашем.exe, а затем сохраните свой client.exe.2.manifest как "client.manifest", то все системы должны работать.

Простое объяснение заключается в том, что файл.manifest не используется. Что весьма вероятно в этом сценарии, ваш.exe почти наверняка уже содержит манифест, встроенный в качестве ресурса. Очень часто в приложении MFC для включения визуальных стилей. И для кода, скомпилированного компиляторами VS2005 или 2008, который встраивает манифест для поиска DLL времени выполнения.

Чтобы убедиться в этом, используйте File + Open + File и выберите скомпилированный.exe-файл. Ищите узел RT_MANIFEST. Если Windows обнаружит такой встроенный манифест, она не будет продолжать искать файловый манифест. Вам нужно объединить ваши regfree COM записи во встроенную. Хотелось бы дать вам хорошую ссылку на MSDN Library, но документы о манифестах - это отстой.

Другие вопросы по тегам