I have to communicate with a third party application and the only way to do so is by accessing the provided COM component. Because the interaction takes about 3 minutes it’s mandatory that it takes place in the background.
So what i tried to do is to add a reference the component with option “embedd interop-types” = true and to create a test that reads very basic data through the interface. The documented way to do so is by following Code:
System sys = new System();
if(Convert.ToBoolean(sys.Initialize()) && Convert.ToBoolean(sys.Login("John Smith", out userInstance)))
Project proj = new Project();
if (Convert.ToBoolean(proj.Open(sys, m_projName, m_scenarioName)))
someValue = proj.Name;
this works perfectly until the BackgroundWorker is used. Then I get following error in the first line of code:
Unable to cast COM object of type ‘System.__ComObject’ to interface type ‘ICAPILib.System’. This operation failed because the QueryInterface call on the COM component for the interface with IID ‘{1F5EB3E2-35F6-11D2-A191-0060083A260B}’ failed due to the following error: Error loading type library/DLL. (Exception from HRESULT: 0x80029C4A (TYPE_E_CANTLOADLIBRARY)).
I already tried ReRegistering the Component without any success.
When using the BackgroundWorker the Thread Apartment Type obviously is MTA. The COM component has ThreadingModel set to apartment. If I understood this article
http://msdn.microsoft.com/en-us/library/eaw10et3.aspx
correctly the interop marshalling should take care of accessing the Objects.
Does anybody have a clue what I could try to make this work?
What has happenned is that the COM Marshaller was unable to marshal the object.
First answer: Standard marshalling requires a type library. It may be that the object’s type library is not correctly registered, hence the error. Are you on x86 or x64? Try registering the library with REGTLB.
Second answer: If that doesn’t work, the easy answer is to use a thread of STA apartment type. This may mean you cannot use a BackgroundWorker but may have to use a specially created thread which you destroy when completed. If we are talking about a three minute operation, the additional overhead is negligible.
Note the object must be created on the thread from which it is to be used, and the apartment type msut be compatible with the object’s threading model, to avoid marshalling.