首先,我對整個COM場景都非常陌生,以至於對我來說如此光禿禿的。InvalidCastException,在COM組件上調用QueryInterface失敗
我正嘗試在.net應用程序中使用PCAnywhere的Ole自動化我目前正在開發(VS 2010,c#)。 PCA 12.5帶有一對tlb文件,當我嘗試通過VS添加引用時,我在兩個語句中都得到一個錯誤:'無法添加對'E:\ Dev \ PcaOle \ awrem32.tlb'的引用。請確保該文件是可訪問的,並且它是一個有效的程序集或COM組件。',所以我做的是使用tlbimp.exe生成互操作程序集,並管理將創建的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);
),它說以下內容的異常:
無法投類型的COM對象winawsvr.CRemoteDataManagerClass「接口類型「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上執行此操作的文檔。