如何正确处理频繁更改的.Net Windows服务

时间:2012-07-07 00:35:37

标签: .net windows-services

我有一个Windows服务,它将在每两周更新一次

我已经在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 个答案:

答案 0 :(得分:3)

不是包装控制台应用程序,而是在服务中启动新的AppDomain,并将dll(插件样式)加载到新的AppDomain中并在那里调用您的方法。这样停止时你可以拆掉AppDomain,释放dll以供你更换。

加载dll插件样式使您无需持有程序集引用。额外的AppDomain允许您卸载dll程序集而不会破坏服务AppDomain(通常是一种不愉快的体验)。

我会避免包装控制台应用程序,因为服务通常不能很好地与UI应用程序配合使用。您的控制台窗口仍将生成UI(控制台窗口)。

答案 1 :(得分:2)

您不需要可执行文件。您可以在启动服务时动态加载DLL。手动执行此操作(请参阅此link),或使用MEF之类的内容为您加载。

另一种简单方法是使用TopShelf来托管您的服务。使用TopShelf,您可以将服务作为控制台应用程序进行开发和运行。将参数install传递给控制台应用程序时,它将作为服务安装。由于您不需要安装人员,因此可以轻松更换。