title: How to diagnose COM-callable wrapper object creation failure?
body: <p>I am creating a COM object (from native code) using <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms686615%28v=vs.85%29.aspx"><code>CoCreateInstance</code></a>:</p>
  
  <pre><code>const 
     CLASS_GP2010: TGUID = "{DC55D96D-2D44-4697-9165-25D790DD8593}";
  
  hr = CoCreateInstance(CLASS_GP2010, nil, CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER, IUnknown, out unk);
  </code></pre>
  
  <p>Actually, I'm in Delphi, which means I call the helper function:</p>
  
  <pre><code>CreateComObject(CLASS_GP2010);
  </code></pre>
  
  <p>Most of the time this function succeeds. But <em>sometimes</em>, in the same executable, in the same <strong>process</strong>, the call to <code>CoCreateInstance</code> fails with:</p>
  
  <pre><code>Unspecified error (0x80004005 = E_FAIL)
  </code></pre>
  
  <p>Calling the function again may succeed, or may fail. There's no (apparent) rhyme or reason.</p>
  
  <h2>It's not my COM dll</h2>
  
  <p>If this were a <em>normal</em> COM dll that I wrote, I would start placing <code>OutputDebugString</code> in <code>DLL_ATTACH</code>, and when someone tries to call <code>DllGetClassObject</code>, I would confirm that COM is correctly loading my DLL, and that it is correctly asking for a class to be instantiated.</p>
  
  <p>Unfortunately it's not a COM dll; it's a .NET assembly dll. And the COM subsystem <a href="https://si0.twimg.com/profile_images/2230187991/siM.png">does not simply</a> <em>"load"</em> my <code>dll</code>. Instead, COM is instructed to load <code>mscoree.dll</code>:</p>
  
  <pre><code>HKEY_CLASSES_ROOT
     CLSID
        {DC55D96D-2D44-4697-9165-25D790DD8593}
           InprocServer32
              @default = mscoree.dll
  </code></pre>
  
  <p>And <code>mscoree.dll</code> exports the required <code>GetClassObject</code> function. So <code>mscoree.dll</code> is the one returning <code>E_FAIL</code>, not me. The failure never happens on my development machine, but consistently intermittently fails on the customers machines. </p>
  
  <h2>How do I enable .NET logging?</h2>
  
  <p>The question is, since <code>mscoree.dll</code> is the one returning <code>E_FAIL</code> (rather than anything useful): how do I have it tell me what the problem is?</p>
  
  <p>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 <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/dd758089%28v=vs.85%29.aspx">cannot load different versions of the .NET runtime into the same process</a>:</p>
  
  <blockquote>
    <p>doing so introduces a CLR version dependency which may conflict with the CLR version expected by the host process</p>
  </blockquote>
  
  <p>This mode of failure is also noted in <a href="http://msdn.microsoft.com/en-us/library/eew13bza.aspx">an article on MSDN when using COM wrappers</a>; where you have the <em>option</em> of specifying a <code>clrVersion</code>:</p>
  
  <blockquote>
    <p>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.</p>
  </blockquote>
  
  <p>If this <strong>were</strong> the cause of my intermittent load failure on Windows XP, or with previous versions on the .NET framework, how can I get the <code>mscoree.dll</code> to tell me that?</p>
  
  <p>If the cause is something else, how do I get .NET to tell me that?</p>