此问题基于另一个问题: How can a windows service programmatically restart itself?
我在上一个问题中实现了其中一个解决方案,如下所示:
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()
我发现有两个问题:
Windows detected your registry file is still in use by other applications or services... 5 user registry handles leaked from ...
这是完整的代码:
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语句有效吗?
答案 0 :(得分:1)
我认为以这种方式执行此操作的最佳方法是运行批处理文件而不是内联命令集。这样,批处理文件可以运行“net stop”并获得错误,而不会影响正在运行的其他语句的错误。
您是否使用services.msc中的服务注册将服务“失败”(异常终止)记录到事件日志中?如果没有,你只是告诉它“重启服务”如果可执行文件因任何原因退出,那么这很简单;相反,调用Application.Exit(),服务可执行文件将正常终止,然后Windows将重新启动它。
就注册表句柄而言,如果您的服务正在使用注册表数据,则OnStop方法应该延迟程序退出,直到清除所有句柄;这意味着必须告知所有后台线程取消并允许优雅地执行此操作(这反过来意味着必须开发线程进程,而不必简单地“杀死”它们就可以取消),所有打开的文件和注册表流必须关闭并妥善处置,一般而言,服务不得留下任何“磨损的目的”。在这些事情发生时,OnStop()可以将程序执行延迟大约10秒;如果您的服务需要的时间比完全退出的时间长,Windows将会出错,并且您的服务最终会停止但不会重新启动。
答案 1 :(得分:0)
这个适合你吗? (我公然宣传自我推销的类似答案) link to answer to similar problem