【问题标题】:Detecting a scheduled shutdown检测计划关闭
【发布时间】:2011-09-03 14:45:09
【问题描述】:

我有一个 cmd 脚本,它将执行一组补丁,如果需要重新启动以避免补丁问题,它会中止。如果计划重新启动(例如通过“关闭”命令),我还想扩展脚本以中止,以便尽可能避免在补丁中重新启动。不幸的是,除了尝试安排另一次关机之外,我还没有找到一种方法来检测这种情况,这会导致:

已安排系统关闭。(1190)

虽然我理论上可以使用它,但我认为每次我需要检查是否有计划的重启时吓跑已登录的用户并不是一个好习惯。我真正需要的是一种查询“关闭”命令修改的状态的方法。

这可能吗?我真的会对任何不涉及让我在系统上永久运行应用程序来捕获关闭事件的解决方案感到满意(我认为在实际触发关闭之前甚至不会发送)

【问题讨论】:

    标签: windows winapi system-shutdown


    【解决方案1】:

    我想您可以使用Task Scheduler API 枚举计划任务并查看其中是否有调用shutdown.exe。但我不确定这是否可靠。可能有多种方法可以安排关机。

    【讨论】:

    • 是的,不幸的是有几种方法,到目前为止我还没有弄清楚“shutdown /r /t 60”命令是如何安排它的。它似乎不是一个计划任务——它可能是一个低得多的级别,如果没有明确的 API 就很难检测到:(
    【解决方案2】:

    也许您可以尝试通过调用ExitWindowsEx 来启动关机,并在较大的宽限期内检查返回码ERROR_SHUTDOWN_IS_SCHEDULED,如果ExitWindosEx 返回成功(表明您已成功调度),则立即调用AbortSystemShutdown关机)

    【讨论】:

    • 感谢您的建议。我将其视为最后的手段,因为我真的不想将机器上的任何用户与定期的“机器重新启动”、“开玩笑”通知混淆。
    【解决方案3】:

    我也有同样的问题,找遍了,没找到有用的东西。

    最终,我开始胡思乱想各种我能想到的东西。对于我们的问题,我可以想到两种解决方法。

    事件查看器可以告诉您已安排关闭,但不能告诉您安排的时间。

    一个想法是向事件查看器查询最近的系统关闭、最近的预定关闭和预定关闭的最近取消。如果计划的关闭比最近的取消或关闭更近,则有一个正在进行中。 事件 ID 是: 1074 开始计划关机, 1075 用于取消计划关机,在 Windows 日志/系统下 12 系统启动 13 系统关机 (全部在 Windows 日志/系统下)

    我懒得在批处理文件中执行此操作,但我知道这是可能的。

    所以这就是我最终做的事情: 与其安排关机,不如尝试中止它。如果没有正在进行关机,它将引发错误(无法中止系统关机,因为没有正在进行关机。(1116))。我认为这比通过安排关机来吓坏用户要好得多。

    这是我为一个简单的自动关机脚本编写的代码副本,它在取消和启动预定关机之间切换。

    @echo off
    shutdown /a
    if errorlevel 1 call:shutdown
    goto end
    
    :shutdown
        set /p choice=Shutdown in how many minutes? 
        set /a mod=60
        set /a mod*=%choice%
        shutdown /s /t %mod%
    
    :end
    

    编辑 - 我正在重新审视这个答案,因为我有更多信息要添加。

    上述解决方案将检测是否已通过使用 /t 参数的 shutdown.exe 命令安排关机。

    如果您需要确定 Windows 是否已安排关机(在某些 Windows 更新后会自动进行),那么您可以查询一个已设置的注册表项。以下是在 PowerShell 中,但您可以编写一个批处理文件来执行相同的操作。

    Test-Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending'
    

    注意:如果使用shutdown.exe按计划重新启动,则不会返回true,仅当Windows说您的计算机需要重新启动时才会返回true。

    【讨论】:

      【解决方案4】:

      如果您的脚本设置关闭,另一种方法是使用 setx 命令将 %date% 和 %time% 变量保存到全局环境中。然后您可以在下次调用脚本时检查这些变量。

      【讨论】:

        【解决方案5】:

        你可以使用:

        Shutdown /a "用于中止预定"

        然后再次使用 shutdown 来创建另一个计划。

        【讨论】:

          猜你喜欢
          • 2019-11-10
          • 1970-01-01
          • 2023-03-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-11-01
          相关资源
          最近更新 更多