【问题标题】:Windows service start, stop, debug problemsWindows服务启动、停止、调试问题
【发布时间】:2011-09-25 07:24:29
【问题描述】:

我有一个我不知道运行时间的服务,我猜大概是 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;

    }

【问题讨论】:

  • 使用异常处理并记录异常...它将帮助您找到问题
  • 视情况而定,但您检查过您的事件日志吗?
  • 我应该在 OnStart() 和 OnStop() 中添加一个例外 我没有从 GetListingsFromSp() 获得例外
  • 这段代码是在您的服务中还是在某些测试程序中?因为service.Stop() 应该停止您的服务,如果这是您服务中的代码,这对我来说似乎很奇怪(看这里:msdn.microsoft.com/en-us/library/…

标签: c# windows windows-services


【解决方案1】:

将服务配置为在调试器下启动: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。

【讨论】:

  • 我按照页面上的说明进行操作。我正在获取windbg屏幕。但我无法理解任何输出。我无法复制或获取它的屏幕截图。但除了“找不到符号文件”之外没有其他重要消息
  • @Haditok 您需要 SOS 扩展来在 WinDBG 中进行 .NET 调试并整理对符号文件的访问(最简单的方法:将它们与 exe/dll 文件并排放置)。很多关于使用 WinDBG 的在线帮助以及一些好书。
【解决方案2】:

理想情况下,您希望调试服务的 OnStart 方法以查看发生了什么。这是可能的:

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

即使服务未标记为桌面交互,这也有效。

【讨论】:

    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多