简体   繁体   中英

COM Interop issues, inconsistent behavior between dev machine and client machine

I have a solution, that compiles and interops with a legacy COM object without issue on my dev machine.

When I deploy the application via ClickOnce (or copy/paste the bin dir contents manually to the VM), I get the following:

Unable to cast COM object of type 'System.__ComObject' to interface type 'DBCCTRLLib.IHistory'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{5CD1A1BC-1837-11D3-84CE-0090272DBE04}' failed due to the following error: No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)).

This happens when I try to call a particular piece of functionality from the COM object which I was not utilizing before. All prior interop with the COM/ActiveX function correctly without issue.

I'm stumped, as I don't know how to proceed from here - I'm a COM interop rookie. It runs fine on my dev machine, moving it to a VM or deploying via ClickOnce results in the above failure.

The Interop.DBCCTRLLib.dll is set to Isolated . AxDBCCTRLLib.dll is just set as default (auto generated when added to a WinForm via the toolbox).

The "No such interface supported" is making me think I have a dll mismatch of some sort, but I don't know where/what/how to check.

[Edit: 12/3/2013] I have since cleaned my system of all occurences of the DLLs in question, and did the same for all VM test environments. I am able to run a test project that simply accesses the COM object and performs a query - successfully. I can copy this test project to a VM and it works. If I do the same with my main projects solution, it fails as before. I have verified that all of the DLLs in question are exactly the same between the two projects - one works, one does not. Both projects reference the COM object in exactly the same way, although the main project does launch the COM object on a new STA thread.

There are two basic reasons for E_NOINTERFACE:

  • DLL Hell, the version of the component you are running isn't the same version you compiled your program with. This happens when the original author modified the IHistory interface and, as required by COM, modified the guid of the interface. So your program asks for the old interface (5CD1A1BC-1837-11D3-84CE-0090272DBE04) but it isn't there anymore.

  • Threading Hell, you are calling an IHistory method on a thread that's different from the thread that created the original COM object. COM goes looking for a way to marshal the call to keep the component thread-safe but can't find the proxy/stub do get the job done. As a last gasp it will query for IMarshal and that's not implemented either (it rarely is) so it gives up the ghost with E_NOINTERFACE. Could be because you forgot to copy the proxy/stub DLL, could be because the component simply doesn't support it at all.

These are just hints to get you start looking in the correct corner, not enough to nail it down. It would have helped a lot if you had posted the content of the generated .manifest file. The threadingModel, typelib and comInterfaceExternalProxyStub elements play a significant role in the 2nd bullet. Contacting the author of the component for support would be very wise.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM