Category Archives: Threading

COM Interop – QueryInterface not supported (E-NOINTERFACE)

Problem

Encountering an error when trying to instantiate COM objects through Primarary Interop Assemblies (PIA’s) or Runtime Callable Wrappers (RCW’s) created using the TLBIMP.exe tool. 

When calling the object for the first time, you encounter the following COM exception:

Unable to cast COM object of type ‘xxx to interface type ‘xxx’. This operation failed because the QueryInterface call on the COM component for the interface with IID ‘{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}’ failed due to the following error: No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)).

You are likely to encounter this problem when developing ASP.Net applications, Windows Console applications, or Windows Services.  You are unlikely to experience this issue when developing Windows Forms applications.

Solution

The problem is that you are attempting to call Single-Threaded Apartment (STA) model COM components from an Multi-Threaded Apartment (MTA) thread.  The primary thread of Windows Forms applications are STA threads, so the components work fine there.  Most other project types, including Console applications and Windows Service applications are run on an MTA thread by default.  When you attempt to instantiate the an STA component, you will get the ubiquitous error described above.

You might try calling System.Threading.Thread.CurrentThread.SetApartmentState(ApartmentState.STA), but this won’t work.  You cannot change the thread execution model on a running thread. 

To fix the problem, you can set the thread execution type on the main application thread before it is started, but this is not optimal.  It is better to set the threading model specifically for the portion of code that needs it.

A better solution is to spin up a new thread for the job at hand, and set the thread execution state on the new thread before executing it.  There are a few different methods to accomplish this depending on what you’re trying to accomplish.  Here’s one to get you started:

using System.Threading;
...

// Setup an object to host the thread entry point
// Start a process on an MTA thread 
MyThreadedJob jobHost = new MyThreadedJob(jobId);
Thread t = new Thread(new ThreadStart(MyThreadedJob.Execute));
t.SetApartmentState(ApartmentState.MTA);

// Start the thread
t.Start();

// Wait for thread to complete (optional)
t.Join();

 

More Gory Details

For more of the gory details and differences between threading models in Windows and COM, you can start here.

 

  del.icio.us it! digg it! reddit! technorati! yahoo!