.net delphi com ccw com-callable-wrapper

.net - ¿Cómo diagnosticar la falla de creación de objetos de contenedor COM-llamable?



delphi ccw (2)

Al menos, si tuviera que ejecutarlo en el depurador de Visual Studio, es posible que pueda detectar las excepciones de primera oportunidad y obtener información. Por lo menos, desea saber qué tipo de error resulta en E_FAIL. Debería poder hacer esto incluso si no tiene los símbolos de depuración.

Además, incluso si no puede cargar varias máquinas virtuales de .NET en el mismo proceso, con algunos trabajos manuales con los manifiestos App.config y .dll, es posible que pueda cargar los archivos .dll en la misma máquina virtual de .NET aunque fueron compilados contra uno diferente.

Finalmente, verifique el visor de eventos de Windows debajo de los eventos de la aplicación para ver si hay algo allí registrado.

Estoy creando un objeto COM (desde código nativo) usando CoCreateInstance :

const CLASS_GP2010: TGUID = "{DC55D96D-2D44-4697-9165-25D790DD8593}"; hr = CoCreateInstance(CLASS_GP2010, nil, CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER, IUnknown, out unk);

En realidad, estoy en Delphi, lo que significa que llamo a la función de ayudante:

CreateComObject(CLASS_GP2010);

La mayoría de las veces esta función tiene éxito. Pero a veces , en el mismo ejecutable, en el mismo proceso , la llamada a CoCreateInstance falla con:

Unspecified error (0x80004005 = E_FAIL)

Volver a llamar a la función puede tener éxito o puede fallar. No hay (aparente) rima o razón.

No es mi dll COM

Si esto fuera un dll COM normal que escribí, comenzaría a colocar OutputDebugString en DLL_ATTACH , y cuando alguien intente llamar a DllGetClassObject , confirmaría que COM está cargando correctamente mi DLL, y que está pidiendo correctamente que se DllGetClassObject una instancia de una clase. .

Desafortunadamente no es un dll COM; es un dll de ensamblaje de .NET. Y el subsistema COM no simplemente "carga" mi dll . En cambio, se le ordena a COM que cargue mscoree.dll :

HKEY_CLASSES_ROOT CLSID {DC55D96D-2D44-4697-9165-25D790DD8593} InprocServer32 @default = mscoree.dll

Y mscoree.dll exporta la función GetClassObject requerida. Así que mscoree.dll es el que devuelve E_FAIL , no yo. La falla nunca ocurre en mi máquina de desarrollo, pero sistemáticamente falla de manera intermitente en las máquinas de los clientes.

¿Cómo habilito el registro de .NET?

La pregunta es, ya que mscoree.dll es el que devuelve E_FAIL (en lugar de algo útil): ¿cómo puedo decirme cuál es el problema?

Por ejemplo, parece que los únicos clientes que experimentan el error (además de ser los únicos que usan mucho el objeto COM) están en Windows XP. Quizás estén experimentando el error conocido en .NET Framework (anterior a la versión 4) donde no se pueden cargar diferentes versiones del tiempo de ejecución de .NET en el mismo proceso :

al hacerlo, introduce una dependencia de versión CLR que puede entrar en conflicto con la versión CLR que espera el proceso de host.

Este modo de falla también se menciona en un artículo en MSDN cuando se utilizan envolturas COM ; donde tienes la opción de especificar una clrVersion :

Si ya se ha cargado otra versión del CLR y la versión especificada se puede cargar lado a lado en proceso, se carga la versión especificada; de lo contrario, se utiliza el CLR cargado. Esto podría causar una falla de carga.

Si esta fue la causa de mi falla de carga intermitente en Windows XP, o con versiones anteriores en .NET Framework, ¿cómo puedo obtener el mscoree.dll para decirme eso?

Si la causa es otra cosa, ¿cómo consigo que .NET me diga eso?


Puede usar la función de registro de errores de ensamblaje: debe estar habilitada y luego puede usar el visor de registro de fusión para ver los resultados http://msdn.microsoft.com/en-us/library/e74a18c4(v=vs.110).aspx No estoy seguro de cómo conseguirá esto en las máquinas de sus clientes.

La primera vez que leí esto, mi primer pensamiento fue el que parece más común en win xp boxes. Este es un problema de la versión de .net / bit o su dll de .net no tiene una dependencia que no esté presente en estas máquinas.