Есть COM сервер. Это, в общем, Outlook, но на данном этапе, как мне кажется, это неважно. Есть DLL, которая сидит в адресном пространстве этого COM сервера. И вот очень хотелось бы получить доступ в одном из методов этой ДЛЛ к COM серверу. Что я делаю:
1) Импортирую все как положенно.
2) Выполняю где-то такой код:
...
CoInitialize(NULL);
Если этот код написан в тестовом exe, то он отрабатывает ОТЛИЧНО — использует уже запущенный Outlook. Если же этот код выполняется в DLL, которая уже сидит в адресном пространстве COM сервера (в данном случае — как старомодный не-COM плугин) — то это счастье виснет на вызове OleRun в дебрях строчки OL::_ApplicationPtr ........ на приличное время (порядка 4х минут), после чего вываливается с ошибкой 0x80080005 — Server execution failed. В это же время в Task Manager можно наблюдать попытки запустить второй Outlook.exe — видимо, чтобы получить этот самый Outlook.Application.
Встречался ли кто-либо с таким необычным поведением? Почему этот код просто не начинает использовать уже запущенный COM сервер?..
Здравствуйте 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. Один раз.
Потестировать код для его использования я еще не успел, но если кому будет интересен сей опыт, то добро пожаловать.
Здравствуйте MaksymS, Вы писали:
MS> Можно и так, но в конструкторе _com_ptr есть возможность и так управлять pOuter и CLSCTX. Просто эти параметры передаются как дополнительные.
Да мтожно и _com_ptr использвать. Но я его не перевариваю.
Ладно. Ты все понял совершенно правильно.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.