InvalidCastException, QueryInterface call failing on COM component

3.4k views Asked by At

I'm trying to use PCAnywhere's Ole automation in a .net applicaction I'm currently developing (VS 2010, c#). PCA 12.5 comes with a couple tlb files that when I try to add as references through VS I get an error on both saying 'A reference to 'E:\Dev\PcaOle\awrem32.tlb' could not be added. Please make sure that the file is accessible, and that it is a valid assembly or COM component.', so what I did is generate the interop assemblies using tlbimp.exe and managed to import the created DLLs as references no problem. OK. Here's the bit of code I have so far:

Thread pcat = new Thread(delegate()
{
    CRemoteDataManagerClass mng = new CRemoteDataManagerClass();
    RemoteDataExClass data = null;
    data = (RemoteDataExClass)mng.RetrieveObjectEx("temp.chf", (short)2, null);
    if (data == null)
        data = (RemoteDataExClass)mng.CreateObjectEx("temp.chf");
    data.ConnectionType = "TCP/IP";
    data.PhoneNumber = host.IP;
    data.AutoLoginName = host.Nombre.StartsWith("WS") ? "usrwksvc" : "admonadn";
    data.AutoDomain = "dom" + actual.numec.PadLeft(4, '0');
    data.WriteProtection = false;
    data.WriteObject(null);
    AWREM32.Document doc = new AWREM32.Document();
});
pcat.SetApartmentState(ApartmentState.STA);
pcat.Start();
pcat.Join();

CRemoteDataManagerClass, RemoteDataExClass, and AWREM32.Document are classes within the assemblies.

So I get an exception on the 5th line (data = (RemoteDataExClass)mng.RetrieveObjectEx("temp.chf", (short)2, null);) which says the following:

Unable to cast COM object of type 'winawsvr.CRemoteDataManagerClass' to interface type 'winawsvr.IRemoteDataManager'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{82A1A806-8BA9-11CF-B95F-00A02412C812}' failed due to the following error: Interfaz no compatible (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)).

What could I be missing here? Maybe something with the way the COM components are registered? They previously were before I even tried to register them with regasm.exe, only the CLSID's had LocalServer32 keys within them. After i ran regasm.exe this created two, I believe: InprocHandler32 and InprocServer32. I got the same exception before and after.

I read somewhere that I needed to run the calling code within a thread set to STA apartment state. So I did. Still no change.

Another thing I noticed is when I ran ildasm.exe against the interop assembly where the failing class is located I can see within the IRemoteDataManager the line: .custom instance void [mscorlib]System.Runtime.InteropServices.GuidAttribute::.ctor(string) = ( 01 00 24 38 32 41 31 41 38 30 36 2D 38 42 41 39 // ..$82A1A806-8BA9 .... IRemoteDataManager with the TLB has the GUID 82A1A806-8BA9-11CF-B95F-00A02412C812 which is the same GUID mentioned in the exception. The first two sections of this GUID is found on that line I mention from ildasm (I guess the rest is just cut out for display issues), so everything seems to be fine there, too.

I've tried using CRemoteDataManager (which is the interface that implements IRemoteDataManager) instead of CRemoteDataManagerClass, but same deal. In both cases the exception always mentions CRemoteDataManagerClass anyways. From what I can see in ildasm CRemoteDataManagerClass implements both CRemoteDataManager and IRemoteDataManager. Maybe QueryInterface is failing on one of the two, or something else entirely.

I don't know. I'm obviously all over the place here.

I also looked into interop logging to maybe see why exactly QueryInterface is failing, but all I've found is documentation on how to do that on the .netcompactframework.

1

There are 1 answers

0
Jimmie Clark On

It appears to me that

data = (RemoteDataExClass)mng.RetrieveObjectEx("temp.chf", (short)2, null);

might have an issue. The (RemoteDataExClass) I believe is trying to cast the mng to its type before the .RetrieveObjectEx is called. This could give your error. The other option could be that one of the class object doesn't like the New operator. I have noticed in various situations where these libraries offer the new operator that give errors, but there are other classes with a Create function of sorts. Using those one might get the Created class you need to do your retrieve.