Как диагностировать сбой COM-вызываемого объекта создания обертки?
Я создаю 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 сказать мне это?
Ответы
Ответ 1
По крайней мере, если вы запустили его в отладчике Visual Studio, вы сможете поймать исключения с первым шансом и получить некоторое представление. По крайней мере, вы хотите знать, какая ошибка возникает в E_FAIL. Вы должны это сделать, даже если у вас нет символов отладки.
Кроме того, даже если вы не можете загружать несколько .NET VM в один и тот же процесс, используя некоторую ручную работу с манифестом App.config и .dll, вы можете загрузить DLL в той же VM. даже если они были скомпилированы против другого.
Наконец, просмотрите средство просмотра событий Windows в рамках событий приложения, чтобы узнать, есть ли там что-либо.
Ответ 2
Вы можете использовать функцию регистрации сбоев сбоя сборки - она должна быть включена, а затем вы можете использовать средство просмотра журнала слияния, чтобы увидеть результаты
http://msdn.microsoft.com/en-us/library/e74a18c4 (v = vs .110).aspx
Не знаете, как вы получите это на своих компьютерах клиентов.
Когда я впервые прочитал это, моя первая мысль была дана, она кажется наиболее распространенной в win xp box, это проблема .net/bit wise или ваша .net dll отсутствует зависимость, не присутствующая на этих машинах.