How to diagnose COM-callable wrapper object creation failure?

28

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?

.net
delphi
com
ccw
com-callable-wrapper
asked on Stack Overflow Jul 24, 2013 by Ian Boyd • edited May 16, 2014 by Ian Boyd

2 Answers

0

At the very least, if you were to run it in Visual Studio's debugger, you might be able to catch the first-chance exceptions and get some insight. At the very least, you want to know what kind of error results in the E_FAIL. You should be able to do this even if you don't have the debug symbols.

Additionally, even if you can't load multiple .NET VM's in the same process, with some manual work with the App.config and .dll manifests, you might be able to load the .dll's in the same .NET VM even though they were compiled against a different one.

Finally, check the windows event viewer under the application events to see if there is anything logged there.

answered on Stack Overflow Aug 7, 2013 by Arafangion
0

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.

answered on Stack Overflow Jun 29, 2014 by Hargrovm

User contributions licensed under CC BY-SA 3.0