Подтвердить что ты не робот

Как диагностировать сбой 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 сказать мне это?

4b9b3361

Ответ 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 отсутствует зависимость, не присутствующая на этих машинах.