【问题标题】:How can I reject a Windows "Service Stop" request in ATL 7?如何在 ATL 7 中拒绝 Windows“服务停止”请求?
【发布时间】:2011-02-05 19:16:03
【问题描述】:

我有一个基于 ATL 7 的 CAtlServiceModuleT 类的 Windows 服务。该服务提供系统上各种应用程序使用的 COM 对象,如果服务在它们仍在运行时停止,这些其他应用程序自然会开始出错。

我知道如果 CComModule 的 GetLockCount() 返回 0,ATL DLL 会通过在 DllCanUnloadNow() 返回 S_OK 来解决这个问题。也就是说,它会检查以确保当前没有人使用 DLL 提供的任何 COM 对象。我想要服务中的等效功能。

这是我在覆盖 CAtlServiceModuleT::OnStop() 时所做的:

void CMyServiceModule::OnStop()
{
    if( GetLockCount() != 0 ) {
        return;
    }

    BaseClass::OnStop();
}

现在,当用户尝试从“服务”面板停止服务时,他们会看到一条错误消息:

Windows 无法停止本地计算机上的 XYZ 服务。 该服务没有返回错误。这可能是内部 Windows 错误或内部服务错误。 如果问题仍然存在,请联系您的系统管理员。

Stop 请求确实被拒绝了,但它似乎使服务处于错误状态。第二个停止请求会导致此错误消息:

Windows 无法停止本地计算机上的 XYZ 服务。

错误 1061:服务目前无法接受控制消息。

有趣的是,这次服务确实停止了(尽管我不希望它停止,因为仍然有未完成的 COM 引用)。

我有两个问题:

  1. 服务在被询问时拒绝停止是否被认为是不好的做法?
  2. 是否有礼貌的方式表示停止请求被拒绝;一个不会使服务进入不良状态的服务?

【问题讨论】:

  • 我绝对认为当用户询问时不停止是一种不好的做法。除非您完全确信您的服务没有错误,否则您会强制他们重新启动,或者更糟糕的是,如果您的服务发生意外情况。

标签: com windows-services atl


【解决方案1】:

你不能这样做。一旦 SCM 向您的服务发送 SERVICE_CONTROL_STOP,您就必须停止。

如果您的其他应用程序也是服务,您可以在 SCM 中使它们成为依赖项。当然,如果使用该服务的应用只是普通应用,是不能使用的。

【讨论】:

    【解决方案2】:

    当 ATL 的锁计数增加到 1 时,调用 SetServiceStatus() 并在 SERVICE_STATUS::dwControlsAccepted 字段中省略 SERVICE_ACCEPT_STOP 标志。那么您将根本不会收到任何SERVICE_CONTROL_STOP 请求。任何停止服务的尝试都会立即失败。当 ATL 的锁计数回落到 0 时,再次调用 SetServiceStatus() 并指定 SERVICE_ACCEPT_STOP 标志。

    我只需要在 2 个(较旧的)基于 ATL 的服务中执行此操作,并且效果很好。诚然,我无法找出直接覆盖 Lock() 和 Unlock() 的最佳方法,所以我只是在我的服务中放置了一个小循环,它会定期检查 GetLockCount() 并在需要时调用 SetServiceStatus()

    【讨论】:

      【解决方案3】:

      在您的构造函数中,更新m_status.dwControlsAccepted 删除SERVICE_ACCEPT_STOP。例如:

      CMyServiceModule::CMyServiceModule()
          : ATL::CAtlServiceModuleT<CMyServiceModule, IDS_SERVICENAME>()
      {
          m_status.dw &= ~SERVICE_ACCEPT_STOP
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-01-31
        • 1970-01-01
        相关资源
        最近更新 更多