2011-06-28 51 views
3

以下方法是DCOM服務器方法。 COM客戶端和服務器在不同的WinXP計算機上運行。 COM客戶端調用RegisterClient方法來註冊回調接口。問題是QueryInterface方法失敗,錯誤代碼爲E_ACCESSDENIED。這個問題的原因是什麼?QueryInterface失敗,E_ACCESSDENIED

STDMETHODIMP CGEMExtension::RegisterClient(IUnknown** ppGEMExtensionEvents, int* nClientId, int* nResult) 
{ 
    HRESULT hRes = (*ppGEMExtensionEvents)->QueryInterface(IID_IGEMExtension,(void**)&pUnknown); 
    return hRes; 
} 

回答

3

當您獲得E_ACCESSDENIED時,這意味着您有權限問題(請勿在防火牆或註冊中佔用您的時間 - 前者會引發錯誤,告訴您服務不可用,而後者會告訴您該課程未註冊等)。 COM依賴於Windows權限,所以這是你應該關注的。

在你的情況,如果我理解正確的情況下,服務器實際上調用客戶端,以獲得正確的接口。爲此,運行服務器的用戶應該在客戶端擁有正確的權限。幾點建議:

  1. 正如daramarak所建議的,讓服務器和客戶端使用相同的域用戶或具有相同密碼的同一本地用戶。
  2. 在客戶端上,將this setting設置爲「classic」。
  3. 給服務器的用戶,如果知道客戶端,使用DCOMCNFG額外的權限。
+0

+1非常好的答案,我會建議使用alt。1,同時讓所有的東西都能正常工作,並且在一切正常運行時使用dcomcnfg進行配置,還可以使用dcom api中包含的安全功能來獲取正確的權限。 – daramarak

+0

我們有兩個DCOM服務器。 QueryInterface方法對DCOM服務器A正常工作。在這種情況下,客戶端對象是使用CoCreateInstance方法創建的。在失敗的情況下,該對象是使用CComObject :: CreateInstance(&pExtensionSink)創建的。這將是原因 – Maanu

+0

@Maanu我不知道。一切都一樣嗎?我認爲問題出在服務器端,但我可能會錯過一些東西。我不確定這是否適合您的情況,但在調用QueryInterface之前嘗試[在ppGEMExtensionEvents上設置安全毯](http://msdn.microsoft.com/zh-cn/library/ms692692.aspx)。首先在客戶端硬編碼本地管理員的一些用戶名和密碼,如果有效,請通過一種真正靈活的解決方案。 – eran

1

這可能是因爲其他計算機上的權限錯誤。最簡單的方法是使用secpol打開日誌記錄(本地策略,審覈策略,打開登錄事件和對象訪問的日誌記錄),然後可以看到您是否嘗試訪問另一臺計算機。

如果你只是測試那麼我會建議使用設置「作爲交互用戶運行」,在組件服務COM對象,並確保您有兩臺機器相同的密碼相同的用戶。然後,您必須以客戶端計算機上的普通用戶身份運行。特別將用戶設置爲普通用戶也是可能的。

作爲一般的建議,調試DCOM連接:關閉所有的防火牆和等,以確保工作的連接,然後逐個打開安全措施,確保你離開了正確的端口打開並且正確的用戶擁有正確的權限。

0

我給你,即使它可能並不直接適用於您的具體情況,我的經驗。

在Windows 7 64位在我有x64和32位編譯一個dll編譯一個exe。

一個COM對象住在dll裏面。

exe(由「普通」用戶啓動)創建COM對象(在同一臺計算機上)請求IUnknown並且創建成功。然後exe通過QueryInterface請求不同的接口,並且失敗E_ACCESSDENIED

如果我以「administrator」身份啓動exe,那麼QueryInterface將返回S_OK

我沒有進一步的調查,我懷疑有大約32位的一些政策 - 64位的相互作用。

相關問題