Как диагностировать сбой создания 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 DLL
Если бы это был обычный COM dll, который я написал, я бы начал размещать OutputDebugString
в DLL_ATTACH
и когда кто-то пытается позвонить DllGetClassObject
Я бы подтвердил, что COM правильно загружает мою DLL, и что он правильно запрашивает создание экземпляра класса.
К сожалению, это не COM DLL; это сборка.NET DLL. И подсистема 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 Framework (до версии 4), из-за которой вы не можете загрузить разные версии среды выполнения.NET в один и тот же процесс:
при этом вводится зависимость от версии CLR, которая может конфликтовать с версией CLR, ожидаемой хост-процессом
Этот режим сбоя также отмечается в статье на MSDN при использовании COM-оболочек; где у вас есть возможность указать clrVersion
:
Если другая версия CLR уже загружена и указанная версия может быть загружена параллельно в процессе, указанная версия загружается; в противном случае используется загруженный CLR. Это может вызвать сбой загрузки.
Если это было причиной моего прерывистого сбоя загрузки в Windows XP или в предыдущих версиях.NET Framework, как я могу получить mscoree.dll
сказать мне это?
Если причина в чем-то другом, как мне заставить.NET сказать мне это?
2 ответа
Вы можете использовать функцию регистрации ошибок привязки сборки - ее необходимо включить, а затем вы можете использовать программу просмотра журнала Fusion, чтобы просмотреть результаты http://msdn.microsoft.com/en-us/library/e74a18c4%28v=vs.110%29.aspx Не уверен, как вы получите это на своих клиентских компьютерах.
Когда я впервые прочитал это, мне впервые пришла в голову мысль, что на win xp boxs наиболее часто встречается проблема с версией.net / bit, или в вашей.net dll отсутствует зависимость, отсутствующая на этих машинах.
По крайней мере, если вы запустите его в отладчике Visual Studio, вы сможете поймать исключения первого шанса и получить некоторое представление. По крайней мере, вы хотите знать, какая ошибка приводит к E_FAIL. Вы должны быть в состоянии сделать это, даже если у вас нет символов отладки.
Кроме того, даже если вы не можете загрузить несколько виртуальных машин.NET в одном процессе, при некоторой ручной работе с манифестами App.config и.dll вы можете загрузить файлы DLL в одну виртуальную машину.NET, даже если они были скомпилированы против другого.
Наконец, проверьте средство просмотра событий Windows под событиями приложения, чтобы увидеть, есть ли там что-нибудь зарегистрированное.