Непонятное поведение COM сервера
От: MadMax  
Дата: 11.01.02 17:58
Оценка:
Здравствуйте, уважаемые!

Вопросец вот есть... Никак сам не разберусь.

Есть COM сервер. Это, в общем, Outlook, но на данном этапе, как мне кажется, это неважно. Есть DLL, которая сидит в адресном пространстве этого COM сервера. И вот очень хотелось бы получить доступ в одном из методов этой ДЛЛ к COM серверу. Что я делаю:

1) Импортирую все как положенно.
2) Выполняю где-то такой код:
...
CoInitialize(NULL);

try
{
OL::_ApplicationPtr pOutlook("Outlook.Application");
OL::_NameSpacePtr pNameSpace = pOutlook->GetNamespace("MAPI");
}
catch (_com_error &e)
{
dump_com_error(e);
}

CoUninitialize();

Если этот код написан в тестовом exe, то он отрабатывает ОТЛИЧНО — использует уже запущенный Outlook. Если же этот код выполняется в DLL, которая уже сидит в адресном пространстве COM сервера (в данном случае — как старомодный не-COM плугин) — то это счастье виснет на вызове OleRun в дебрях строчки OL::_ApplicationPtr ........ на приличное время (порядка 4х минут), после чего вываливается с ошибкой 0x80080005 — Server execution failed. В это же время в Task Manager можно наблюдать попытки запустить второй Outlook.exe — видимо, чтобы получить этот самый Outlook.Application.

Встречался ли кто-либо с таким необычным поведением? Почему этот код просто не начинает использовать уже запущенный COM сервер?..

Заранее спасибо!
Re: Непонятное поведение COM сервера
От: VladD2 Российская Империя www.nemerle.org
Дата: 11.01.02 18:24
Оценка:
Здравствуйте MadMax, Вы писали:

Вызывай CoCreateInstance явно и поиграй с флагами (описание в MSDN).
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Непонятное поведение COM сервера
От: MaksymS Великобритания  
Дата: 12.01.02 13:26
Оценка:
Здравствуйте VladD2,

VD>Вызывай CoCreateInstance явно и поиграй с флагами (описание в MSDN).


Можно и так, но в конструкторе _com_ptr есть возможность и так управлять pOuter и CLSCTX. Просто эти параметры передаются как дополнительные.

В любом случае, поигрался я и с этим, и с CoInitializeEx — и выяснил, в чем дело. Логика работы COM в этом случае такова:

1) Ага, запрашиваемый сервер ("Outlook.Application") — не CLSCTX_INPROC_SERVER (не зарегистрирован как таковой).
2) Ага, запрашиваемый сервер — CLSCTX_LOCAL_SERVER.
3) Из 2 следует, что выполняться он должен в отличном от текущего процессе.
4) Из 3 следует, что нужно запустить новый процесс, в котором должен OleRun новый Local сервер.
5) Из логики запуска Outlook, который не дает запуститься более чем одной своей копии, запускается новый процесс, обнаруживает работающую копию и пытается передать ей управление — но работающая копия УЖЕ заблокирована вызовом CoCreateInstance.
6) ОБЛОМ.

Что интересно — Микрософт предусмотрела такую ситуацию и создала еще один интерфейс IOutlookExtCallback, который можно получить из стандартного IExchExtCallback, и который, собственно, должен возвращать требуемый IUnknown и IDispatch. Но интерфейс этот явно в MSDN не документирован, нигде в хедерах не упоминается, а есть только короткое его упоминание в статье "Microsoft Outlook and Exchange Client Extensions", которая опубликованна в MSDN. Один раз.

Потестировать код для его использования я еще не успел, но если кому будет интересен сей опыт, то добро пожаловать.
Re[3]: Непонятное поведение COM сервера
От: VladD2 Российская Империя www.nemerle.org
Дата: 12.01.02 21:39
Оценка:
Здравствуйте MaksymS, Вы писали:

MS> Можно и так, но в конструкторе _com_ptr есть возможность и так управлять pOuter и CLSCTX. Просто эти параметры передаются как дополнительные.


Да мтожно и _com_ptr использвать. Но я его не перевариваю.

Ладно. Ты все понял совершенно правильно.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.