InvalidCastException,QueryInterface调用COM组件失败

时间:2010-08-04 00:25:06

标签: c# com ole queryinterface

我正在尝试在我正在开发的.net应用程序中使用PCAnywhere的Ole自动化(VS 2010,c#)。 PCA 12.5附带了几个tlb文件,当我尝试通过VS添加作为引用时,我得到一个错误,两个都说“对'E:\ Dev \ PcaOle \ awrem32.tlb'的引用”无法添加。请确保该文件是可访问的,并且它是一个有效的程序集或COM组件。',所以我所做的是使用tlbimp.exe生成interop程序集并设法导入创建的DLL作为引用没问题。好。 这是我到目前为止的一些代码:

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和AWREM32.Document是程序集中的类。

所以我在第5行(data = (RemoteDataExClass)mng.RetrieveObjectEx("temp.chf", (short)2, null);)上得到一个例外,其中包含以下内容:

无法将“winawsvr.CRemoteDataManagerClass”类型的COM对象强制转换为接口类型“winawsvr.IRemoteDataManager”。此操作失败,因为对IID为“{82A1A806-8BA9-11CF-B95F-00A02412C812}”的接口的COM组件的QueryInterface调用由于以下错误而失败:Interfaz不兼容(HRESULT异常:0x80004002(E_NOINTERFACE))。

我在这里可以缺少什么?可能与COM组件的注册方式有关吗?他们以前在我尝试使用regasm.exe注册它们之前,只有CLSID的内部有LocalServer32密钥。我运行regasm.exe后创建了两个,我相信:InprocHandler32和InprocServer32。我之前和之后都有同样的例外。

我在某处读到了我需要在设置为STA单元状态的线程中运行调用代码。所以我做了。仍然没有变化。

我注意到的另一件事是当我对失败类所在的互操作程序集运行ildasm.exe时,我可以在IRemoteDataManager中看到行.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 ...。带有TLB的IRemoteDataManager具有GUID 82A1A806-8BA9-11CF-B95F-00A02412C812,它与异常中提到的GUID相同。这个GUID的前两部分是在我从ildasm提到的那一行上找到的(我猜其余部分只是因为显示问题而被删除),所以一切似乎都很好。

我已经尝试过使用CRemoteDataManager(它是实现IRemoteDataManager的接口)而不是CRemoteDataManagerClass,但同样的交易。在这两种情况下,异常总是提到CRemoteDataManagerClass。从我在ildasm中看到的内容,CRemoteDataManagerClass实现了CRemoteDataManager和IRemoteDataManager。也许QueryInterface在两者中的一个上完全失败,或者其他完全失败。

我不知道。我显然在这里到处都是。

我也研究了interop日志记录,可能会看到为什么QueryInterface确实失败了,但我发现的是关于如何在.netcompactframework上执行此操作的文档。

1 个答案:

答案 0 :(得分:2)

在我看来

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

可能有问题。我相信(RemoteDataExClass)试图在调用.RetrieveObjectEx之前将mng转换为它的类型。这可能会给你的错误。另一个选项可能是其中一个类对象不喜欢New运算符。我注意到在各种情况下这些库提供了给出错误的新运算符,但是还有其他类具有各种类型的Create函数。使用那些可能会获得您需要进行检索的Created类。