2012-07-07 47 views
2

我有這將被更新〜每兩週如何正確處理一個.net窗口服務,勤換

我已經有了一個DLL中的所有有用的代碼,該服務的窗口服務只是簡單的StartStop方法映射到DLL中的相同方法。

我使用控制檯應用程序開發/調試DLL,所以我想知道;而不是服務直接引用DLL並且每次執行更新時都需要卸載/重新安裝,那麼使用服務來包裝控制檯應用程序是否有任何缺點?

這就是說,而不是...

Private MyService as IMyService 
Sub Start() 
    MyService = New MyService() 
    MyService.StartAsync() 
End Start 

做這樣的事情......

Const ServiceExecutablePath As String = "C:\Blah\MyService.exe" 
Private MyService as Process 
Sub Start() 
    MyService = Process.Start(ServiceExecutablePath) 
End Start 

這樣,如果我要發佈,所有我需要做的是停止該服務,替換可執行文件(和相關的DLL),然後再次啓動它。

我還沒有完全搞清楚如何做一個優雅的關機呢。控制檯應用程序偵聽CTRL   C中斷和調用MyService.Shutdown(Graceful:=True)(阻塞調用)。我應該嘗試從服務內模仿還是有更好的方法?

回答

2

你不需要一個可執行文件。您可以在啓動服務時動態加載DLL。您可以手動執行此操作(請參閱此link),也可以使用諸如MEF之類的內容爲您加載。

另一個簡單的方法是使用TopShelf來承載您的服務。藉助TopShelf,您可以開發和運行您的服務作爲控制檯應用程序。當您將參數安裝傳遞給控制檯應用程序時,它將作爲服務安裝。由於您不需要安裝程序,因此可以輕鬆更換。

+0

我們已經在整個DI中使用了Unity。我知道MEF,但沒有使用它。我希望將服務中的代碼保持在絕對最低限度,以減少難以調試問題的風險。我需要多少? – Basic 2012-07-07 00:46:40

+0

MEF易於安裝(它現在是.net框架的一部分),可以與DI容器並排使用,因爲DI不是主要目標,而是副作用。看看例子。 – Fernando 2012-07-07 01:00:09

+0

@Basic,請看看這個TopShelf的例子:http://topshelf-project.com/documentation/shelving/。 – Fernando 2012-07-07 01:02:51

3

而不是包裝控制檯應用程序,我會在服務中啓動一個新的AppDomain,並將dll(插件樣式)加載到新的AppDomain中並在那裏調用您的方法。這種方式停下來你可以拆卸AppDomain,它釋放你的替代享受的dll。

加載dll插件樣式讓您無需持有程序集引用。額外的AppDomain可以讓你卸載dll程序集,而不會破壞AppDomain服務(通常是一個不愉快的體驗)。

我會避免包裝控制檯應用程序,因爲服務通常不會很好地用於UI應用程序。您的控制檯窗口仍然會生成一個UI(控制檯窗口)。

+1

這是一個很好的建議,謝謝 - 有了額外的好處,我不需要將'Stop' /'Start'翻譯成控制檯。我也可以更容易地處理異常。 – Basic 2012-07-07 00:44:27