【问题标题】:ServiceController status does not correctly reflect the actual service statusServiceController 状态不能正确反映实际服务状态
【发布时间】:2012-08-30 07:39:55
【问题描述】:

如果我的服务正在启动或停止,我会让这段代码运行一个 powershell 脚本。

Timer timer1 = new Timer();

ServiceController sc = new ServiceController("MyService");

protected override void OnStart(string[] args)
    {
        timer1.Elapsed += new ElapsedEventHandler(OnElapsedTime);
        timer1.Interval = 10000;
        timer1.Enabled = true;
    }

    private void OnElapsedTime(object source, ElapsedEventArgs e)
    {
        if ((sc.Status == ServiceControllerStatus.StartPending) || (sc.Status ==  ServiceControllerStatus.Stopped))
        {
            StartPs();
        }
    }

    private void StartPs()
    {
        PSCommand cmd = new PSCommand();
        cmd.AddScript(@"C:\windows\security\dard\StSvc.ps1");
        PowerShell posh = PowerShell.Create();
        posh.Commands = cmd;
        posh.Invoke();
    }

当我从 cmd 提示符终止我的服务时,它工作正常 但即使我的服务已启动并正在运行,powershell 脚本也会继续自行执行(它会在计算机上附加一个文件) 知道为什么吗?

【问题讨论】:

  • 说powershell与这个问题正交是否正确,而真正的问题是:为什么我的StartPending/Stopped检查不能正常工作?
  • 你试过设置断点看看到底发生了什么吗?

标签: c# windows-services


【解决方案1】:

ServiceController.Status 属性并不总是有效的;它在第一次被请求时被延迟评估,但(除非被请求)那一次;对Status 的后续查询不会通常检查实际服务。要强制执行此操作,请添加:

sc.Refresh();

在您的.Status 检查之前:

private void OnElapsedTime(object source, ElapsedEventArgs e)
{
    sc.Refresh();
    if (sc.Status == ServiceControllerStatus.StartPending ||
        sc.Status == ServiceControllerStatus.Stopped)
    {
        StartPs();
    }
}

没有sc.Refresh(),如果最初是Stopped(例如),它会总是Stopped

【讨论】:

  • 呃!认真的,微软?为什么不对Status 调用本身进行刷新(就像我最终可能会自己做一样)?或者至少有一个Status.Refresh 方法让它显而易见。
  • 哇! @Marc 你让我开心。理解我们必须调用 sc.Refresh() 来确定最新状态并不明显。
猜你喜欢
  • 2021-09-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-27
  • 2023-02-13
  • 1970-01-01
  • 2021-11-20
  • 1970-01-01
相关资源
最近更新 更多