отладка COM бесплатная регистрация (с ++) - PullRequest
7 голосов
/ 16 февраля 2011

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

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

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


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

  • модулей, которые у меня есть:
    • клиент MFC, который зависит от 2 COM-серверов (dll1.dll и dll2.dll)
    • dll1.dll COM-сервер зависит от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 ]

6 голосов
/ 16 февраля 2011

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

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

2 голосов
/ 17 февраля 2011

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

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

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

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

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

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

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

...