Я создаю COM-объект (из собственного кода) с помощью CoCreateInstance
:
const
CLASS_GP2010: TGUID = "{DC55D96D-2D44-4697-9165-25D790DD8593}";
hr = CoCreateInstance(CLASS_GP2010, nil, CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER, IUnknown, out unk);
Собственно, я в Delphi, что означает, что я вызываю вспомогательную функцию:
CreateComObject(CLASS_GP2010);
В большинстве случаев эта функция завершается успешно. Но иногда, в том же исполняемом файле, в том же процессе, вызов CoCreateInstance
завершается с ошибкой:
Unspecified error (0x80004005 = E_FAIL)
Вызов функции снова может преуспеть или может выйти из строя. Там нет (кажущейся) рифмы или разума.
Это не моя COM-библиотека
Если бы это была нормальная COM-библиотека DLL, которую я написал, я бы начал размещать OutputDebugString
в DLL_ATTACH
, а когда кто-то пытается вызвать DllGetClassObject
, я бы подтвердил, что COM правильно загружает мою DLL и что это правильно запрашивает экземпляр класса.
К сожалению, это не COM-dll; это DLL сборки .NET. И подсистема COM не просто "загружает" мой dll
. Вместо этого COM получает команду загрузить mscoree.dll
:
HKEY_CLASSES_ROOT
CLSID
{DC55D96D-2D44-4697-9165-25D790DD8593}
InprocServer32
@default = mscoree.dll
И mscoree.dll
экспортирует требуемую функцию GetClassObject
. Итак, mscoree.dll
- это возвращающий E_FAIL
, а не я. Сбой никогда не происходит на моей машине разработки, но постоянно прерывается на компьютерах клиентов.
Как включить ведение журнала .NET?
Вопрос в том, что mscoree.dll
- это возвращающий E_FAIL
(а не что-нибудь полезное): как мне это сказать, в чем проблема?
Например, похоже, что только клиенты, испытывающие сбой (помимо единственных, которые сильно используют объект COM), находятся в Windows XP. Возможно, они испытывают известную ошибку в платформе .NET(до версии 4), где вы не можете загружать разные версии среды выполнения .NET в тот же процесс:
для этого вводится зависимость версии CLR, которая может конфликтовать с версией CLR, ожидаемой хост-процессом.
Этот способ отказа также отмечается в статье о MSDN при использовании COM-оберток; где у вас есть возможность указать clrVersion
:
Если другая версия CLR уже загружена и указанная версия может быть загружена бок о бок в процессе, загружается указанная версия; в противном случае используется загруженная CLR. Это может привести к сбою нагрузки.
Если этот был причиной моего прерывистого сбоя загрузки в Windows XP или предыдущими версиями на платформе .NET, как я могу заставить mscoree.dll
сказать мне это?
Если причина - это что-то еще, как мне заставить .NET сказать мне это?