2012-05-02 57 views
6

我有一位客戶/合作伙伴試圖使用我們公開的COM功能將他們的應用程序與我們的應用程序相關聯。到目前爲止,他們已經有了一個COM對象,它代表了我們軟件包的一個實例,然後使用我們的COM方法以編程方式爲用戶構建了一些基於他們在應用程序中完成的工作。它本質上是一個「導出」功能。在.NET中釋放COM對象的「所有權」

他們要求我做的事情,我不知道該怎麼做才能讓用戶決定何時關閉實例。我的意思是當我們的軟件包被加載時,它是可見的並且由用戶進行交互。當他們完成後,他們自然地點擊右上角的十字,退出軟件。這不起作用,因爲COM對象在其應用程序中仍處於「活動」狀態。我們的軟件包只能通過終止任務管理器中的進程來關閉,而通過COM加載它的應用程序保持打開狀態。一旦他們的申請退出,我們的申請將自動關閉。由於COM調用,它們的應用程序似乎「擁有」了我們的應用程序。

我在C#中製作了一個快速演示應用程序,嘗試使用諸如Marshal.FinalReleaseComObject(myObject)之類的東西無濟於事。

我意識到使用COM來處理這種事情並不是真正的目的,但希望有一些解決方法?客戶/合作伙伴正在使用VB.NET,但C#很好。

+0

請澄清,如果您的應用程序是從應用程序本身(類似於VS或Office應用程序中的VBA腳本)或從外部(類似於使用Word自動化從您自己的控制檯應用程序/腳本創建新文檔)自動執行的? –

+0

他們無法關閉窗口?這沒有意義,你需要澄清。 –

+0

從外面看,他們使用VB通過引用我們的exe並從中實例化一個COM對象來啓動一個新的進程。我們有一個「Open」,它聽起來像是什麼,打開我們軟件包的可用窗口。在不能夠關閉該窗口而言,你不能單擊紅色的X在右上角,以及你可以,但沒有任何反應。它只會在VB應用程序關閉時關閉。我不知道了很多關於COM互操作,但它似乎像VB應用程序有所有權或者是進程的父進程。 – sxthomson

回答

3

您已經忽略了一些關於您自己的應用程序的重要信息,包括最重要的是如何實現您公開給客戶端應用程序的COM接口。你的描述的一個方面是我的紅旗是你的應用程序的實例化。你說客戶端應用程序是「使用VB通過引用我們的exe來啓動一個新的進程」。如果你已經正確地實現並註冊了你的COM服務器,這應該不是必需的。讓我告訴你我將用來完成你所要求的架構,並希望這將對你有用。

首先,如果你想從一個單獨的進程中提供一個COM對象,正確的方法是實現一個COM out of process服務器。使用進程外服務器時,當客戶端通過COM請求您的某個接口時,COM將自動啓動您的應用程序。部分失步服務器的實施要求是在最後一個COM客戶端釋放其最後的接口指針時自動關閉。

爲了從進程外服務器公開用戶界面,您需要生成一個帶有消息循環的獨立單線程單元(STA)線程。這將允許您關閉STA線程上的任何窗口,包括主窗口,而不會終止您的COM服務器。這是因爲COM服務器實現將運行它自己的多線程公寓(MTA)消息循環線程,以支持來自proc調用的COM。 MTA線程是主應用程序線程,並且服務器將在最後一個客戶端界面發佈時關閉它。

COM服務器不應該在接口保持未釋放狀態時關閉。這意味着客戶端應用程序有責任正確地釋放接口。但是你的.NET測試框架應該做到這一點,所以你的實現看起來有些不對。

假設您遵循此指導原則,您將需要一個計劃來處理最後一個客戶端界面發佈的場景,但您仍然擁有開放的UI窗口。一旦你正確地設置了一切,這應該不是一個主要問題。例如,您可以簡單地在UI打開時引用您自己的某個接口,這樣可以防止MTA關閉。