Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to diagnose COM-callable wrapper object creation failure?

I am creating a COM object (from native code) using CoCreateInstance:

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

Actually, I'm in Delphi, which means I call the helper function:

CreateComObject(CLASS_GP2010); 

Most of the time this function succeeds. But sometimes, in the same executable, in the same process, the call to CoCreateInstance fails with:

Unspecified error (0x80004005 = E_FAIL) 

Calling the function again may succeed, or may fail. There's no (apparent) rhyme or reason.

It's not my COM dll

If this were a normal COM dll that I wrote, I would start placing OutputDebugString in DLL_ATTACH, and when someone tries to call DllGetClassObject, I would confirm that COM is correctly loading my DLL, and that it is correctly asking for a class to be instantiated.

Unfortunately it's not a COM dll; it's a .NET assembly dll. And the COM subsystem does not simply "load" my dll. Instead, COM is instructed to load mscoree.dll:

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

And mscoree.dll exports the required GetClassObject function. So mscoree.dll is the one returning E_FAIL, not me. The failure never happens on my development machine, but consistently intermittently fails on the customers machines.

How do I enable .NET logging?

The question is, since mscoree.dll is the one returning E_FAIL (rather than anything useful): how do I have it tell me what the problem is?

For example, it appears that the only customers experiencing the failure (besides being the only ones who heavily use the COM object) happen to be on Windows XP. Perhaps they are experiencing the known bug in the .NET framework (prior to version 4) where you cannot load different versions of the .NET runtime into the same process:

doing so introduces a CLR version dependency which may conflict with the CLR version expected by the host process

This mode of failure is also noted in an article on MSDN when using COM wrappers; where you have the option of specifying a clrVersion:

If another version of the CLR is already loaded and the specified version can be loaded side-by-side in-process, the specified version is loaded; otherwise, the loaded CLR is used. This might cause a load failure.

If this were the cause of my intermittent load failure on Windows XP, or with previous versions on the .NET framework, how can I get the mscoree.dll to tell me that?

If the cause is something else, how do I get .NET to tell me that?

like image 466
Ian Boyd Avatar asked Jul 24 '13 14:07

Ian Boyd


1 Answers

You can use the assembly binding failure logging feature - it needs to be enabled and then you can use the fusion log viewer to see the results http://msdn.microsoft.com/en-us/library/e74a18c4(v=vs.110).aspx Not sure how you will get this onto your clients machines.

When I first read this my first thought was given it seems most common on win xp boxes is this a .net version/ bit wise problem or is your .net dll missing a dependency not present on these machines.

like image 179
Hargrovm Avatar answered Oct 18 '22 20:10

Hargrovm