2014-01-23 83 views
1

我有一個進程外com服務器,指定CLSCTX_LOCAL_SERVER作爲上下文,REGCLS_MULTIPLEUSE作爲連接類型。這會導致單個服務器進程被多個客戶端的多個調用重用。進程外COM服務器 - 每個調用進程有一個服務器進程?

我現在想對服務器進行一些更改,但不幸的是無法使用客戶端之間共享的單個進程(這是有原因的,但是他們很長時間)。我知道你可以設置服務器使用REGCLS_SINGLEUSE作爲連接類型,這將爲每次調用OOP服務器創建一個新的進程。這解決了我的問題,但在流程使用方面卻不是首發;短時間內多次調用會導致很多進程,並且這個特定的服務器可能會經常遭遇難以置信的攻擊。

有沒有人碰巧知道混合這兩種連接類型的機制?基本上我想要的是每個調用進程的單個服務器進程。 (即,客戶端創建一個進程,並且該進程被重用於來自該客戶端的後續調用,客戶端2嘗試調用服務器,並創建一個新進程)。我懷疑我可以通過強制REGCLS_SINGLEUSE服務器在客戶端永久保持打開狀態來實現它,但這既不優雅也不可能(因爲我無法更改其中一個客戶端)。

想法?

UPDATE 正如所料,似乎沒有辦法做到這一點。如果時間和資源允許,我很可能會將其轉換爲In-Proc解決方案。但現在,我不得不採用任何呼叫客戶端使用的新行爲。幸運的是,這種變化的影響非常小,並且被客戶所接受。稍後我會研究更激烈和適當的更改。

注意 我已標記漢斯的答案回答,因爲它事實上確實給一個解決的維護OOP解決的問題。我只是沒有能力實施它。

cal

+0

所以你想要一個進程內解決方案的所有好處,而不需要它在進程內。這是對的嗎?因爲你所描述的每一個過程(這個過程中的「過程」)恰恰是這樣做的,只有過程隔離是缺失的成分。 – WhozCraig

+0

到目前爲止(這是遺留代碼),我沒有發現任何暗示,它確實需要過程中,並且我個人可能會使它處於進程中。不幸的是,這種改變的規模並不能證明在改變這種情況時需要進行的測試。就目前而言,我將新行爲抹去了面向對象,並接受它稍微改變了老客戶的行爲。 – cal

+0

@cal,最好的解決方案是Hans提到的Application coclass。 – Ben

回答

5

COM不支持此激活方案。它應該被一個進程內服務器所覆蓋,確保它不是你想要這樣做的方式,因爲它有相當大的優勢。

使用REGCLS_SINGLEUSE是另一種選擇,但這需要您擴展對象模型以避免您現在創建的服務器實例的風暴。 Application coclass是樣板模式。爲它提供工廠方法,爲您的實例提供現有接口。

我會提到一個顯着不同的方法,一個時候想解決同樣的問題很好,但需要進程外的一個服務器採取橋接位數差距的優勢我使用。您不會因COM爲您啓動服務器進程而陷入困境,客戶端也可以啓動它。當然,它對服務器的安裝位置足夠了解。現在客戶端當然可以完全控制服務器實例。服務器用改變的CLSID調用CoRegisterClassObject(),我用進程ID對guid的一部分進行了存儲。客戶端做的一樣,所以它總是與正確的服務器連接。客戶端需要額外的代碼才能確保它等待足夠長的時間,以便服務器有機會註冊其對象工廠。工作得很好。

+0

REGCLS_SINGLEUSE基本上是一個非啓動器,代碼本身可以很好地處理多個進程,但客戶端可能會每秒多次觸發該對象,從而創建一個不可接受的資源。 更激烈的方法可行,但我對客戶的訪問有點渺茫,其中兩個已經發布。這個對象的設計有很多不足,不幸的是,測試資源不適用於更劇烈的變化。 – cal

+1

+1。先生,每個客戶端的單個coclass服務器的創造力非常簡單。 「這真棒!」接踵而至。當然不是正常的,但非常優雅。感謝那! – WhozCraig