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;
    }

Windows服务启动、停止和调试问题

将服务配置为在调试器下启动: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只实现一个服务时:

  1. 服务启动(在系统启动时,根据用户请求…(:SCM运行注册的命令行

  2. 运行Main,告诉SCM(通过ServiceBase.Run(这是什么服务。此必须与步骤1中使用的注册相匹配。

  3. 传递给ServiceBase.Run的实例调用了其OnStart。服务应该启动它将要执行的活动,然后返回(即,异步操作、新线程和线程池都可以;在调用OnStart的线程上继续则不行(。

  4. 当要关闭的信号到达(来自任何来源(时,调用OnStop。这将触发停止OnStart启动的(或自那以后启动的(所有活动,并等待它们停止,然后返回。

服务停止自身的唯一原因是其他因素(例如其自己的管理API(触发了它,但最好从UI使用SCM。

理想情况下,您希望调试服务的OnStart方法,看看发生了什么

protected override void OnStart(string[] args)
{
    #if DEBUG
    Debugger.Launch();
    #endif
    ...
}

即使服务未被标记为桌面交互式,这也能起作用。

OnStart和OnStop处理程序有固定的处理时间限制。我不知道停止是如何工作的(是否等待线程完成..(,但对于OnStart,在您的情况下(我知道它是一个旧线程..(,我会将所有应用程序代码移动到计时器回调中,并在OnStart函数中设置计时器。我把我的时间定在1分钟左右。OnStart将立即退出,这满足了服务经理的要求。但现在您有了一个大约一分钟后启动的线程,这使您有时间将进程附加到调试器。显然,在OnStart计时器回调中的第一条指令上设置了一个断点。