2010-08-04 90 views
4

首先,我對整個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上執行此操作的文檔。

回答

2

這在我看來,

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

可能有問題。 (RemoteDataExClass)我相信是在調用.RetrieveObjectEx之前將mng轉換爲它的類型。這可能會導致你的錯誤。另一個選項可能是其中一個類對象不喜歡New運算符。我注意到在各種情況下,這些庫提供給錯誤的新運算符,但還有其他具有創建函數的類。使用這些可能會得到您需要進行檢索的創建類。