这个问题是基于其他问题: How can a windows service programmatically restart itself?问题与Windows服务程序重新启动本身
我实现的解决方案之一在前面的问题,像这样:
Dim proc As New Process()
Dim psi As New ProcessStartInfo()
psi.CreateNoWindow = True
psi.FileName = "cmd.exe"
psi.Arguments = "/C net stop YOURSERVICENAMEHERE && net start YOURSERVICENAMEHERE"
psi.LoadUserProfile = False
psi.UseShellExecute = False
psi.WindowStyle = ProcessWindowStyle.Hidden
proc.StartInfo = psi
proc.Start()
我看到2个问题与此:
- 事件日志每次服务重新启动时引发此警告:
Windows detected your registry file is still in use by other applications or services... 5 user registry handles leaked from ...
- 服务有时可能无法重新启动。在仔细研究之后,我最好的猜测就是该服务在该进程尝试重新启动之前结束。这是一个问题的原因是因为净停止命令将失败,因为服务已经停止,导致它不执行net start命令。
下面是完整的代码:
Private Sub Timer_Elapsed(ByVal sender As System.Object, ByVal e As System.Timers.ElapsedEventArgs) Handles _timer.Elapsed
' we do not want the timer stepping on itself (ie. the time interval elapses before the first call is done processing
_timer.Stop()
' do some processing here
Dim shouldRestart As Boolean = ProcessStuff()
If shouldRestart Then
Dim proc As New Process()
Dim psi As New ProcessStartInfo()
psi.CreateNoWindow = True
psi.FileName = "cmd.exe"
psi.Arguments = "/C net stop ""My Cool Service"" && net start ""My Cool Service"""
psi.LoadUserProfile = False
psi.UseShellExecute = False
psi.WindowStyle = ProcessWindowStyle.Hidden
proc.StartInfo = psi
proc.Start()
Return
End If
_timer.Start()
End Sub
假设我是正确的(重要的假设)有问题2,你认为用了Thread.Sleep(10000)命令更换工作Return语句?
+1对于Onstop的信息。有Windows重新启动它是一个好的选择(见其他评论)。我将不得不使用批处理文件进行测试。该服务可以在任何用户帐户(不仅是本地系统)下运行,在这种情况下,该用户可能没有权限执行批处理文件。不确定,但我会测试。 – 2012-02-10 21:20:05
我刚发现不使用批处理文件的另一个原因。安全!如果服务作为具有高权限的用户运行,我想不出一个更简单的方法来破解它。 – 2012-02-16 16:27:30
如果安全性问题,该服务可以发出自己的批处理文件。这在很大程度上排除了攻击者劫持进程以运行恶意批处理文件的能力,并且不会比任何基于运行cmd.exe和Process.Start()的东西更加依赖“魔术字符串”如果命令需要更改,则必须重新构建应用程序的代价。 – KeithS 2012-02-16 16:34:17