I'm having the problem described in this question: Unable to cast COM object of type exception which manifests as the error:
Unable to cast COM object of type 'System.__ComObject' to interface type 'IMyInterface'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{GUID}' failed due to the follow error: No such interface supported
My WPF app is calling a .NET library that eventually calls a COM object. This works fine, but it runs on the main thread and blocks the UI. When I spawn a new thread and call the library from it, I'm getting that error. None of those solutions on the other question are working for me. I'm trying to understand how the runtime can have the type information loaded, but not share it between threads.
I understand that WPF apps are STA, and I know that means that any objects moving between threads will be COM marshalled. I don't understand how the type information to say "This is a COM object, and its GUID is this" can be in the AppDomain, but inaccessible to the second thread.
Where does loaded type information live? Is it in the AppDomain, or per thread? In any case, how can I make the threads share type information? How can I fix this?
I've read this:
http://www.codeproject.com/Articles/9190/Understanding-The-COM-Single-Threaded-Apartment-Pa
and this:
http://msdn.microsoft.com/en-us/library/ms973913.aspx#rfacomwalk_topic10
and a bunch of other stuff that talks about COM interop, but hasn't helped me fix it.
As per Hans Passant's answer, I'm creating my library object inside the second STA thread:
var thread = new Thread(delegate()
{
var aeroServer = new AeroServerWrapper(Config.ConnectionString);
var ct = new CancellationToken();
aeroServer._server.MessageReceived += ServerMessageReceived;
aeroServer.Go(@"M:\IT\Public\TestData\file.dat", ct);
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
I understand that I might need to call Application.Run() to start the message queue if events fail to fire but I'm not getting that far: it crashes as soon as it attempts to create the COM object. The AeroServerWrapper is in a separate DLL, which calls a second DLL, which finally attempts to instantiate the COM object.
Any hints or articles would be greatly appreciated. I'd like to solve this as it is: my Plan B is to wrap the library in a console app, spawn the console app from the UI, and get status messages from it through a named pipe. That'll work, but it seems ugly.