我有一個C#類&方法,我已經蒸餾至無所事事,但分配的COM對象和執行工藝外的一個C++ COM服務器的調用。COM客戶端將無法訪問C++ COM服務器
eFilm.IEFilm eFilmInterface = (eFilm.IEFilm)Activator.CreateInstance(Type.GetTypeFromProgID("EFilm.Document", true));
eFilmInterface.oleCloseAllWindows();
當我在命令行上以我的登錄用戶身份執行此代碼時,它將生成不足的特權錯誤。如果我然後提升它(或運行一個高架的外殼),它工作正常。它正試圖訪問的COM服務器是一個獨立的應用程序,我登錄到我的用戶後開始。
我,而不是試圖執行在Windows服務這同樣的動作。該服務是VS2012 C#windows服務模板的基本實現,我標記爲.Net 4.0和任何CPU或x86(兩者都失敗)。我試圖在服務的的OnStart實施過程中STA線程上調用(儘管它呈現在OnStart中運行同樣的問題()方法本身):
protected override void OnStart(string[] args)
{
var staThread = new Thread(this.OnStartSTA);
staThread.SetApartmentState(ApartmentState.STA);
staThread.Start();
}
private void OnStartSTA(object threadState)
{
eFilm.IEFilm eFilmInterface = (eFilm.IEFilm)Activator.CreateInstance(Type.GetTypeFromProgID("EFilm.Document", true));
eFilmInterface.oleCloseAllWindows();
}
的的CreateInstance()調用失敗,但有以下例外:
System.Runtime.InteropServices.COMException (0x80080005): Retrieving the COM class factory for component with CLSID {C8CF03E4-FD1F-11D3-8C03-0080C8D3C5D3} failed due to the following error: 80080005 Server execution failed (Exception from HRESULT: 0x80080005 (CO_E_SERVER_EXEC_FAILURE)).
at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck)
at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)
at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)
at System.Activator.CreateInstance(Type type, Boolean nonPublic)
at System.Activator.CreateInstance(Type type)
我已經嘗試將活動會話中的同一用戶更改爲本地系統的服務帳戶。我犯了同樣的錯誤。我已經有服務驗證CLSID是否存在於其註冊表視圖中。我在服務器日誌中找不到任何錯誤(儘管我沒有代碼或調試符號)。 Windows應用程序日誌顯示完全相同的錯誤(可能是因爲它通過鏈式拋出全部通過)。我嘗試將GetTypeFromProgID切換到遠程版本並引用localhost,但它會生成相同的錯誤。
此外,如果我使用命令行版本的應用程序,並通過NSSM生成服務包裝,我會得到完全相同的錯誤。
我不知道什麼是錯的,我也不對如何繼續調試一個非常好的計劃。關於我能想到的所有問題都是用戶上下文的問題,但這似乎是COM應該能夠做到的。另一種選擇是服務器註冊中缺少一些關鍵信息。 I already had issues with that earlier在這個過程中。
編輯:
經過進一步調查,似乎調用企圖COM服務器的結果啓動在任何用戶上下文服務器的新副本服務在,不活躍用戶身份運行上下文。我試圖模仿該用戶,但它沒有改變任何東西。如果我運行具有用戶憑據的服務,你只看到在任務管理器&進程資源管理器相同的用戶運行的應用程序的兩個副本。我懷疑這與服務器的構建或配置有關。
有一件事我覺得有趣,即使我開始與本地系統服務冒充COM調用作爲活動的用戶,COM服務器被作爲啓動系統,而不是用戶。
EDIT2:
通過COM/DCOM設置翻轉,看起來像在DCOM的AppID有一個RunAS which lets you choose interactive user。我的服務器從未註冊過AppID部分。
我手動砍死在的AppID部分來的AppID和CLSID,但它似乎並沒有解決它。它仍然在服務的上下文中產生進程,儘管進程的大小不會增長到它通常所做的全部大小。