我有一个topshelf windows服务,我想做一些检查(即如果存在xml文件),如果检查失败,我需要停止Windows服务。
所以我尝试在Start()方法中进行检查,然后引发异常:
public void Start()
{
if (!File.Exists(_xmlFile) throw new FileNotFoundException();
// Do some work here if xml file exists.
}
然而,在异常之后,Windows服务仍然作为一个进程保留,然后我必须在任务管理器中手动终止。
如果某些条件(即找不到文件)成立,是否有办法不运行服务?
答案 0 :(得分:27)
您可以使用HostControl对象并修改您的方法,如下所示:
public bool Start(HostControl hostControl)
{
if (!File.Exists(_xmlFile)
{
hostControl.Stop();
return true;
}
// Do some work here if xml file exists.
...
}
您需要将HostControl传递给Start方法,如下所示:
HostFactory.Run(conf =>
{
conf.Service<YourService>(svcConf =>
{
svcConf.WhenStarted((service, hostControl) =>
{
return service.Start(hostControl);
}
}
}
答案 1 :(得分:7)
每个WhenXxx方法也可以使用HostControl接口的参数,该参数可用于请求停止服务,请求额外的启动/停止时间等。
在这种情况下,将start()的签名更改为bool start(HostControl hc)。在服务中保留对此HostControl的引用,如下所示:
public bool Start(HostControl hc)
{
hostControl = hc;
Restart();
return true;
}
现在,当您想要停止服务时,请使用以下呼叫:
hostControl.Stop();
答案 2 :(得分:5)
我从Topshelf文档中的最佳实践或建议的角度对此感到好奇,但找不到任何东西。但是,我确实从phatboyg找到了两个单独的评论...
最佳评论...如何通过this issue停止异常服务(我删除了一些细节):
如果服务的Start方法抛出异常,则服务将无法启动。
一旦服务运行,如果抛出未处理的异常,服务将停止,并将其作为崩溃报告给服务控制管理器。
如果需要以编程方式停止服务,请使用HostControl方法停止。
所以我认为最简单的答案是抛出异常。
你这样做了,你提到“Windows服务在异常之后仍然存在”。这似乎是代码中某处不相关的错误,或者您可能以某种方式运行了多个实例?我今天早上一直在测试这些场景,并且在start方法中抛出异常后没有看到我的服务正在运行。
此外,与在接受的答案中提到的HostFactory.Run之前的检查相关,通过https://groups.google.com/forum/embed/#!topic/topshelf-discuss/nX97k3yOhJU:
“您的应用程序除了在调用HostFactory.Run()方法之前配置NLog / Log4Net之外什么都不做。”
答案 3 :(得分:4)
我刚遇到这个问题,所有上述答案似乎都过于复杂。您需要做的就是使用接受WhenStarted
的{{1}}重载,如果内部服务引导失败,则返回false。我不认为Func<T,HostControl,bool>
需要明确调用。
hostControl.Stop()
答案 4 :(得分:2)
我已经&#34;借了&#34; topshelf功能设置的示例代码,用于演示一个要点:
HostFactory.Run(x => //1
{
x.Service<TownCrier>(s => //2
{
s.ConstructUsing(name=> new TownCrier()); //3
s.WhenStarted(tc => tc.Start()); //4
s.WhenStopped(tc => tc.Stop()); //5
});
x.RunAsLocalSystem(); //6
x.SetDescription("Sample Topshelf Host"); //7
x.SetDisplayName("Stuff"); //8
x.SetServiceName("stuff"); //9
});
在上述代码运行之前,您必须检查文件系统。让我们来思考一下。提供服务的关键是确保RUNS和KEEPS RUNNING。您首先试图颠覆拥有服务应用程序的基本原则。而不是因为丢失文件而试图停止服务,而是找出一些方法来提醒您的支持人员,而不是根据丢失的文件做任何事情。
答案 5 :(得分:-3)
当您捕获异常时,可以使用ServiceBase.Stop()
方法自行停止服务。
try
{
// Your Code
}
catch (Exception ex)
{
// The code for stopping service
}
在某些情况下,您还可以使用多个捕获块:
try
{
// Your Code
}
catch (IndexOutOfRengeException ex)
{
// The code for stopping service
}
catch (FileNotFoundException exc)
{
// The code for stopping service
}