.net Windows 服务如何以编程方式自行重启?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/220382/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can a windows service programmatically restart itself?
提问by Ron Harlev
I need to write robust code in .NET to enable a windows service (server 2003) to restart itself. What is the best way to so this? Is there some .NET API to do it?
我需要在 .NET 中编写健壮的代码以启用 Windows 服务(服务器 2003)来重新启动。最好的方法是什么?是否有一些 .NET API 来做到这一点?
回答by TheSoftwareJedi
Set the service to restart after failure (double click the service in the control panel and have a look around on those tabs - I forget the name of it). Then, anytime you want the service to restart, just call Environment.Exit(1)(or any non-zero return) and the OS will restart it for you.
将服务设置为在失败后重新启动(双击控制面板中的服务并查看这些选项卡 - 我忘记了它的名称)。然后,只要您希望服务重新启动,只需调用Environment.Exit(1)(或任何非零返回),操作系统就会为您重新启动它。
回答by Khalid Rahaman
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()
回答by Greg Hewgill
You can't be sure that the user account that your service is running under even has permissions to stop and restart the service.
您无法确定运行服务的用户帐户是否具有停止和重新启动服务的权限。
回答by Greg Hewgill
You can create a process that is a DOS command prompt that restarts yourself:
你可以创建一个进程,它是一个 DOS 命令提示符,它自己重新启动:
Process process = new Process();
process.StartInfo.FileName = "cmd";
process.StartInfo.Arguments = "/c net stop \"servicename\" & net start \"servicename\"";
process.Start();
回答by Filip
const string strCmdText = "/C net stop \"SERVICENAME\"&net start \"SERVICENAME\"";
Process.Start("CMD.exe", strCmdText);
where SERVICENAMEis the name of your service (double quotes included to account for spaces in the service name, can be omitted otherwise).
whereSERVICENAME是您的服务名称(包含双引号以说明服务名称中的空格,否则可以省略)。
Clean, no auto-restart configuration necessary.
干净,不需要自动重启配置。
回答by Brody
It would depend on why you want it to restart itself.
这取决于您为什么希望它重新启动。
If you are just looking for a way to have the service clean itself out periodically then you could have a timer running in the service that periodically causes a purge routine.
如果您只是在寻找一种让服务定期自行清理的方法,那么您可以在服务中运行一个计时器,该计时器会定期导致清除例程。
If you are looking for a way to restart on failure - the service host itself can provide that ability when it is setup.
如果您正在寻找一种在失败时重新启动的方法 - 服务主机本身可以在设置时提供这种能力。
So why do you need to restart the server? What are you trying to achieve?
那么为什么需要重启服务器呢?你想达到什么目的?
回答by user3235770
The problem with shelling out to a batch file or EXE is that a service may or may not have the permissions required to run the external app.
外壳到批处理文件或 EXE 的问题在于服务可能具有或可能没有运行外部应用程序所需的权限。
The cleanest way to do this that I have found is to use the OnStop() method, which is the entry point for the Service Control Manager. Then all your cleanup code will run, and you won't have any hanging sockets or other processes, assuming your stop code is doing its job.
我发现的最简洁的方法是使用 OnStop() 方法,它是服务控制管理器的入口点。然后您的所有清理代码都将运行,假设您的停止代码正在执行其工作,您将不会有任何挂起的套接字或其他进程。
To do this you need to set a flag before you terminate that tells the OnStop method to exit with an error code; then the SCM knows that the service needs to be restarted. Without this flag you won't be able to stop the service manually from the SCM. This also assumes you have set up the service to restart on an error.
为此,您需要在终止之前设置一个标志,告诉 OnStop 方法以错误代码退出;然后 SCM 知道该服务需要重新启动。如果没有此标志,您将无法从 SCM 手动停止服务。这还假设您已将服务设置为在出现错误时重新启动。
Here's my stop code:
这是我的停止代码:
...
bool ABORT;
protected override void OnStop()
{
Logger.log("Stopping service");
WorkThreadRun = false;
WorkThread.Join();
Logger.stop();
// if there was a problem, set an exit error code
// so the service manager will restart this
if(ABORT)Environment.Exit(1);
}
If the service runs into a problem and needs to restart, I launch a thread that stops the service from the SCM. This allows the service to clean up after itself:
如果服务遇到问题并需要重新启动,我会启动一个线程来停止来自 SCM 的服务。这允许服务自行清理:
...
if(NeedToRestart)
{
ABORT = true;
new Thread(RestartThread).Start();
}
void RestartThread()
{
ServiceController sc = new ServiceController(ServiceName);
try
{
sc.Stop();
}
catch (Exception) { }
}
回答by technophile
I don't think you can in a self-contained service (when you call Restart, it will stop the service, which will interrupt the Restart command, and it won't ever get started again). If you can add a second .exe (a Console app that uses the ServiceManager class), then you can kick off the standalone .exe and have it restart the service and then exit.
我不认为你可以在一个自包含的服务中(当你调用 Restart 时,它会停止服务,这会中断 Restart 命令,它永远不会再次启动)。如果您可以添加第二个 .exe(使用 ServiceManager 类的控制台应用程序),那么您可以启动独立的 .exe 并让它重新启动服务,然后退出。
On second thought, you could probably have the service register a Scheduled Task (using the command-line 'at' command, for example) to start the service and then have it stop itself; that would probably work.
再想一想,您可能可以让服务注册一个计划任务(例如,使用命令行“at”命令)来启动服务,然后让它自行停止;那可能会奏效。
回答by dviljoen
I would use the Windows Scheduler to schedule a restart of your service. The problem is that you can't restart yourself, but you can stop yourself. (You've essentially sawed off the branch that you're sitting on... if you get my analogy) You need a separate process to do it for you. The Windows Scheduler is an appropriate one. Schedule a one-time task to restart your service (even from within the service itself) to execute immediately.
我会使用 Windows 调度程序来安排您的服务的重新启动。问题是你不能重启自己,但你可以阻止自己。(您基本上已经锯掉了您所在的分支……如果您理解我的比喻)您需要一个单独的流程来为您完成。Windows 调度程序是合适的。安排一次性任务以重新启动您的服务(甚至从服务本身)以立即执行。
Otherwise, you'll have to create a "shepherding" process that does it for you.
否则,您将不得不创建一个“牧羊”流程来为您完成。
回答by T.E.D.
I don't think it can. When a service is "stopped", it gets totally unloaded.
我不认为可以。当服务“停止”时,它会完全卸载。
Well, OK, there's always a way I suppose. For instance, you could create a detached process to stop the service, then restart it, then exit.
好吧,我想总有办法。例如,您可以创建一个分离的进程来停止服务,然后重新启动它,然后退出。

