Как диагностировать сбой создания 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 под событиями приложения, чтобы увидеть, есть ли там что-нибудь зарегистрированное.

Другие вопросы по тегам