You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何调试Windows Service中的OnStop方法

Windows服务OnStop方法无法调试的解决办法

问题说明

编写了一个Windows Service,OnStart方法中的任务调度器注册逻辑可正常运行且能调试,但OnStop方法无法调试——在Visual Studio中点击停止按钮时,程序直接终止,不会进入OnStop代码段。相关代码如下:

Service1.cs核心代码

protected override void OnStart(string[] args)
{
    // System.Diagnostics.Debugger.Launch(); 

    try
    {
        // 此处代码可正常调试
    }
    catch (Exception ie)
    {
        StreamWriter sw;
        sw = File.AppendText("D:\\DvrService.txt");
        sw.WriteLine(ie.Message);
        sw.Close();
    }
}


protected override void OnStop()
{
    try
    {
         System.Diagnostics.Debugger.Launch();                

        foreach (string key in System.Configuration.ConfigurationManager.AppSettings)
        {
            var chromeDriverProcesses = Process.GetProcesses().Where(pr => pr.ProcessName == key.ToUpper()); // 不带'.exe'

            foreach (var process in chromeDriverProcesses)
            {
                process.Kill();

                StreamWriter sw;
                sw = File.AppendText("E:\\DvrService.txt");
                sw.WriteLine("Trying to kill Service" + key);
                sw.Close();
            }
        }
    }
    catch (Exception ex)
    {
        //TODO: 记录错误
        StreamWriter sw;
        sw = File.AppendText("E:\\DvrService.txt");
        sw.WriteLine("Trying to kill Service");
        sw.Close();
    }
}

Program.cs代码

static void Main()
{
#if DEBUG
    Service1 myService = new Service1();
    myService.onDebug();
    
   
System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite);

#else

    ServiceBase[] ServicesToRun;
            ServicesToRun = new ServiceBase[] 
            { 
                new Service1() 
            };
            ServiceBase.Run(ServicesToRun);

#endif

}

问题原因

当前Debug模式的代码逻辑是直接实例化Service1、调用自定义的onDebug方法后用Thread.Sleep挂起进程,这种方式没有通过ServiceBase.Run来托管服务。Windows服务的生命周期(包括OnStop的触发)由服务控制管理器(SCM)通过ServiceBase托管层管理,直接挂起进程时,Visual Studio点击停止按钮会直接终止进程,不会触发服务的OnStop生命周期方法。

解决办法

方法一:通过服务控制管理器启停服务并附加调试器

  1. 安装服务:编译项目后,使用对应.NET版本的InstallUtil.exe工具安装服务(示例路径:C:\Windows\Microsoft.NET\Framework\v4.0.30319\InstallUtil.exe),执行命令:
    InstallUtil.exe 你的服务程序.exe
    
  2. 启动服务:打开services.msc找到目标服务并启动。
  3. 附加调试器:在Visual Studio中点击菜单「调试」→「附加到进程」,找到服务对应的进程并附加。
  4. 触发OnStop:回到services.msc停止服务,此时调试器会命中OnStop内的断点或Debugger.Launch(),即可正常调试。

方法二:修改Debug模式代码,模拟服务托管环境

修改Program.cs的Debug分支,用ServiceBase.Run托管服务,同时等待用户输入手动触发Stop,这样在Debug模式下可直接触发OnStop并调试:

static void Main()
{
#if DEBUG
    Service1 myService = new Service1();
    // 用线程启动服务托管,避免阻塞主线程
    var serviceThread = new Thread(() => ServiceBase.Run(new ServiceBase[] { myService }));
    serviceThread.IsBackground = true;
    serviceThread.Start();

    Console.WriteLine("服务已启动,按任意键停止服务...");
    Console.ReadKey();

    // 手动调用Stop触发OnStop
    myService.Stop();
    serviceThread.Join();
#else
    ServiceBase[] ServicesToRun;
    ServicesToRun = new ServiceBase[] 
    { 
        new Service1() 
    };
    ServiceBase.Run(ServicesToRun);
#endif
}

修改后,Debug模式运行会弹出控制台窗口,启动服务后按任意键即可触发OnStop方法,正常进行调试。


内容的提问来源于stack exchange,提问作者A.Goutam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 05:50:11