Windows服务启动、停止和调试问题
本文关键字:调试 问题 服务 启动 Windows | 更新日期: 2023-09-27 18:09:39
我有一个服务,我不知道它的运行时间,我想大约是7秒。由于某种原因,服务在第一次运行后停止工作,我无法调试它。它在服务管理器上一直说"启动",而我在附加进程窗口中找不到它。
当我试图停止它时,停止按钮只会出现一秒钟。即使我按下它,我也会收到一个错误,说"windows无法停止服务"本地计算机上的拆分。服务没有返回错误。这可能是内部windows错误或内部服务错误。
处理这个问题的最佳方式是什么?
static void Main(string[] args)
{
ServiceBase.Run(new Program());
ServiceController service = new ServiceController();
service.ServiceName = "SpLive";
service.Start();
//Sp objSportingbet = new Sp();
//objSportingbet.getListingsFromSp();
}
public Program()
{
this.ServiceName = "SpLive";
}
protected override void OnStart(string[] args)
{
base.OnStart(args);
objSportingbet.getListingsFromSp();
timer1.Elapsed += new ElapsedEventHandler(timer1_Elapsed);
timer1.Interval = 7000;
timer1.Enabled = true;
timer1.Start();
}
protected override void OnStop()
{
base.OnStop();
timer1.Elapsed += new ElapsedEventHandler(timer1_Elapsed);
timer1.Interval = 7000;
timer1.Enabled = false;
timer1.Start();
}
private void timer1_Elapsed(object sender, EventArgs e)
{
ServiceController service = new ServiceController();
service.ServiceName = "Sp";
if (service.Status == ServiceControllerStatus.Stopped)
{
service.Start();
}
if (service.Status == ServiceControllerStatus.Running)
{
service.Stop();
}
timer1.Stop();
}
private void InitializeComponent()
{
//
// Program
//
this.CanPauseAndContinue = true;
this.CanShutdown = true;
}
将服务配置为在调试器下启动:http://support.microsoft.com/kb/824344请注意"配置服务以连接WinDbg调试器启动"一节
添加(现在有问题的代码(:
static void Main(string[] args) { ServiceBase.Run(new Program()); ServiceController service = new ServiceController(); service.ServiceName = "SpLive"; service.Start();
ServiceBase.Run(instance)
在服务关闭之前不会返回,因此您正在运行服务,然后在服务关闭后要求SCM运行服务…这只会导致混乱。
这一点,再加上有一个计时器来尝试反转服务的状态(已启动<->已停止(,我认为您需要考虑Windows服务的底层流程模型:
当exe只实现一个服务时:
-
服务启动(在系统启动时,根据用户请求…(:SCM运行注册的命令行
-
运行
Main
,告诉SCM(通过ServiceBase.Run
(这是什么服务。此必须与步骤1中使用的注册相匹配。 -
传递给
ServiceBase.Run
的实例调用了其OnStart
。服务应该启动它将要执行的活动,然后返回(即,异步操作、新线程和线程池都可以;在调用OnStart
的线程上继续则不行(。 -
当要关闭的信号到达(来自任何来源(时,调用
OnStop
。这将触发停止OnStart
启动的(或自那以后启动的(所有活动,并等待它们停止,然后返回。
服务停止自身的唯一原因是其他因素(例如其自己的管理API(触发了它,但最好从UI使用SCM。
理想情况下,您希望调试服务的OnStart
方法,看看发生了什么
protected override void OnStart(string[] args)
{
#if DEBUG
Debugger.Launch();
#endif
...
}
即使服务未被标记为桌面交互式,这也能起作用。
OnStart和OnStop处理程序有固定的处理时间限制。我不知道停止是如何工作的(是否等待线程完成..(,但对于OnStart,在您的情况下(我知道它是一个旧线程..(,我会将所有应用程序代码移动到计时器回调中,并在OnStart函数中设置计时器。我把我的时间定在1分钟左右。OnStart将立即退出,这满足了服务经理的要求。但现在您有了一个大约一分钟后启动的线程,这使您有时间将进程附加到调试器。显然,在OnStart计时器回调中的第一条指令上设置了一个断点。