Windows服务启动,停止,调试问题

时间:2011-09-25 07:24:30

标签: c# windows windows-services

我有一项服务,我不知道运行时间,我估计大约7秒。由于某种原因,服务在第一次运行后停止工作,我无法调试它。它一直在服务管理器上说“启动”,我在附加进程窗口找不到它。

当我尝试停止时,停止按钮仅显示一秒钟。即使我按下它,我也会收到一条错误消息“windows无法停止服务'本地计算机上的Splive。服务没有返回错误。这可能是内部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;

    }

3 个答案:

答案 0 :(得分:3)

将服务配置为在调试器下启动: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开始(或从那时开始)的所有活动,并等待它们停止然后返回。

  5. 服务停止的唯一原因是,如果其他东西(例如它自己的管理API)触发它,但最好是从UI使用SCM。

答案 1 :(得分:3)

理想情况下,您需要调试服务的OnStart方法以查看正在发生的情况。并且有可能:

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

即使服务未标记为桌面互动,也可以使用。

答案 2 :(得分:0)

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