Answers:
将服务设置为在失败后重新启动(双击控制面板中的服务,然后在这些选项卡上四处查看-我忘记了它的名称)。然后,只要您想重新启动服务,只需调用Environment.Exit(1)
(或任何非零返回),操作系统就会为您重新启动。
Service.ExitCode = 1
,然后执行Service.Stop()
并在服务恢复设置屏幕上启用“为错误停止操作启用”复选框。以这种方式执行此操作可以允许正确关闭并仍然触发重新启动。
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()
您无法确定您的服务所运行的用户帐户是否具有停止和重新启动服务的权限。
const string strCmdText = "/C net stop \"SERVICENAME\"&net start \"SERVICENAME\"";
Process.Start("CMD.exe", strCmdText);
SERVICENAME
服务的名称在哪里(包含双引号以说明服务名称中的空格,否则可以省略)。
干净,不需要自动重新启动配置。
炮轰到批处理文件或EXE的问题是,服务可能具有或不具有运行外部应用程序所需的权限。
我发现最干净的方法是使用OnStop()方法,它是服务控制管理器的入口点。然后,所有清除代码都将运行,并且假设您的停止代码正在执行其工作,那么您将没有任何挂起的套接字或其他进程。
为此,您需要在终止之前设置一个标志,该标志告知OnStop方法以错误代码退出。则SCM知道该服务需要重新启动。没有此标志,您将无法从SCM手动停止服务。这也假定您已将服务设置为在发生错误时重新启动。
这是我的停止码:
...
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);
}
如果服务出现问题并需要重新启动,我将启动一个线程,以从SCM停止该服务。这使服务可以自行清理:
...
if(NeedToRestart)
{
ABORT = true;
new Thread(RestartThread).Start();
}
void RestartThread()
{
ServiceController sc = new ServiceController(ServiceName);
try
{
sc.Stop();
}
catch (Exception) { }
}
刚刚过去:我以为我会添加一些额外的信息...
您还可以引发异常,这将自动关闭Windows服务,并且自动重新启动选项也会启动。唯一的问题是,如果您的PC上有开发环境,那么JIT会尝试启动,并且您将得到提示说调试是/否。说不,然后它将关闭,然后重新正确启动。(在没有JIT的PC上,一切正常。)触发的原因是,此JIT是Win 7的新功能(它以前在XP等环境下可以正常工作),并且正在尝试寻找一种禁用JIT的方法...。我可以尝试这里提到的Environment.Exit方法,看看如何也可以。
克里斯蒂安:英国布里斯托尔
像这样创建一个restart.bat文件
@echo on
set once="C:\Program Files\MyService\once.bat"
set taskname=Restart_MyService
set service=MyService
echo rem %time% >%once%
echo net stop %service% >>%once%
echo net start %service% >>%once%
echo del %once% >>%once%
schtasks /create /ru "System" /tn %taskname% /tr '%once%' /sc onstart /F /V1 /Z
schtasks /run /tn %taskname%
然后在%service%启动时删除任务%taskname%
创建一个单独的appdomain来托管应用程序代码。需要重新启动时,我们可以卸载并重新加载appdomain而不是进程(Windows服务)。这就是IIS应用程序池的工作方式,它们不直接运行asp.net应用程序,而是使用单独的appdmain。
private static void RestartService(string serviceName)
{
using (var controller = new ServiceController(serviceName))
{
controller.Stop();
int counter = 0;
while (controller.Status != ServiceControllerStatus.Stopped)
{
Thread.Sleep(100);
controller.Refresh();
counter++;
if (counter > 1000)
{
throw new System.TimeoutException(string.Format("Could not stop service: {0}", Constants.Series6Service.WindowsServiceName));
}
}
controller.Start();
}
}