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

Had*_*Tok 2 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;

    }
Run Code Online (Sandbox Code Playgroud)

Ric*_*ard 5

将服务配置为在调试器下启动: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();
Run Code Online (Sandbox Code Playgroud)

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。