请阅读以下内容:
https://github.com/bitcoin/bitcoin/issues/20052
我问了第一个问题,Github 问题是由其他人创建的,引用了我的 SE 问题。
他们声称 Windows 10 有问题,shutdown /s
无法向正在运行的程序发送“关闭”信号。但这真的是真的吗?这似乎太愚蠢了,不像是真的。如果真是这样,Windows 10 最近肯定发生了变化?
当然,由于我不使用/f
标志强制立即关机,我希望该命令能够完全按照用户以这种方式关闭机器时开始菜单所做的事情执行。但是这个关机命令似乎只是在视觉上通知用户(这是没用的),但没有向正在运行的程序发送任何信号,只是在其内部超时(一分钟?)结束时立即关机。
这是 Windows 10 或 Bitcoin Core 中的错误吗?Bitcoin Core 开发人员似乎确信这是 Windows 的错误,但这始终是 FOSS 开发人员的立场,微软在小更新中随机中断似乎很奇怪?
答案1
shutdown /s
不会向应用程序发送关闭消息,因为这不是它的工作。该命令只是启动正常的 Windows 关机程序,执行一切必要的操作。
无论如何,发送关闭消息都不会很有效。这与应用程序在单击应用程序窗口上的关闭按钮时收到的消息相同。它可以以任何希望的方式处理此消息。
它可以关闭应用程序。如果没有采取任何具体措施,这是默认操作。但应用程序通常会拦截此消息。它可以提示用户保存所有打开的文件或自行执行此操作。它可以将应用程序最小化到通知区域。它可以要求用户确认关闭。或者它什么也不做。
Windows 所做的就是向所有应用程序发送一条消息,告知它们 Windows 即将关闭,它们应该采取一切必要的措施。通常,应用程序会采取一切必要的清理措施,然后关闭。如果应用程序忽略此消息,或者没有及时回复,会话将结束。此时,应用程序无法停止该进程。
从提供的信息来看,没有理由怀疑是 Windows 的问题。不发送此消息将产生严重后果,并且会在测试早期就被发现。我强烈怀疑这是应用程序问题。应用程序的测试水平远不及 Windows。
答案2
一般shutdown /s
不发送任何“关闭”消息。它调用少数几个 Win32 API 函数之一来关闭 Windows 系统。
这些功能反过来通过WM_QUERYENDSESSION
和WM_ENDSESSION
消息通知应用程序有关关机/重启事件。
然后,程序可以同意或尝试通过正确响应来阻止即将关闭的操作WM_QUERYENDSESSION
,例如干净地停止等。
因此,理论上发出shutdown /s
命令后,都会有一些“关闭”消息发送给所有程序,您不需要为此做任何特殊的事情。
但shutdown /s
不知何故,它有点特殊(或有缺陷?),导致 Windows 忽略响应,WM_QUERYENDSESSION
因此 Bitcoin Core 无法干净地关闭。我在 Windows 7 上看到了这种行为,而且从链接的 GitHub 问题中可以看出,Windows 10 也有这种行为。
一个答案这里建议通过 PowerShell 命令执行更“正常”的关机(例如从开始菜单)Stop-Computer
。
在 API 级别,shutdown /s 将使用 InitiateShutdown API 之一(我不确定是哪一个),而 Stop-Computer 最有可能使用 ExitWindowsEx。后者在从交互式会话运行时更合适。
亲自在这种情况下,我从来不信任 Windows,并手动停止任何重要程序。我甚至读过一些关于 Windows 在清理时间过长时会终止应用程序的文章,但现在我找不到了。
您可以阅读有关关机程序的信息这里。
如果你想要的话要旨我用它来进行测试。
答案3
该命令shutdown /s
发出强制重启,如下输出所述shutdown /?
:
/t xxx 设置关机前的超时时间为 xxx 秒。有效范围为 0-315360000(10 年),默认值为 30。 如果超时时间大于 0,则隐含 /f 参数。
/f 强制关闭正在运行的应用程序而不预先警告用户。
[已删节,重点是我的。]
如果您希望应用程序能够取消关机,shutdown /s /t 0
则需要使用。
但这并不能解释为什么你观察到的行为发生了变化。我不确定是 Windows 的行为发生了变化,还是比特币应用程序发生了变化。
我注意到代码在这里在我看来这是不正确的(正如 JdeBp 在另一个答案的评论中指出的那样),并且似乎完全依赖于 ShutdownBlockReasonCreate,而强制关机可能会覆盖它。我相信,如果代码等到客户端关机完成后再响应消息WM_ENDSESSION
,那么客户端关机就可以完成,前提是完成此操作所用的时间不超过五秒钟。
答案4
简短的回答是“否”,当您使用时,Windows 不会在没有通知程序的情况下关闭shutdown /s
。
编辑:正如 Harry Johnston 的回答所指出的那样,这实际上取决于您是否允许超时。我总是使用shutdown /s /t 0
(超时 0 秒),因为默认值是 30 秒,我不想在任何事情发生之前等待一段时间!虽然听起来难以置信,但使用(或默认为) 任何超时时间与可怕的保存行为:Windows 实际上将强制终止您的进程,不给您干预的机会!这种令人恐怖的行为甚至是设计出来的!(请参见使用输出shutdown /?
。)
我的答案是shutdown /s /t 0
,这意味着你不会期望在任何事情发生之前坐在那里长达 30 秒。
您可以亲自演示 Windows 会通知程序。只需在记事本中编辑一个文本文件,然后在保存更改之前输入shutdown /s /t 0
。关机启动时,记事本会阻止关机,并显示它已收到来自 Windows 的通知:
如果您随后按“取消”(或者不采取任何操作),您将返回到 Windows 桌面,其中可以看到记事本提示保存:
然而,Windows 关机功能最近的变化可能引入了一个更微妙的错误:我认为,为了缓解因更新而导致的烦人关机,Windows 最近养成了尝试从上次恢复程序的习惯,这个功能效果不太好,我讨厌它,所以我总是使用shutdown /s /t 0
和shutdown /r /t 0
而不是开始菜单(因为幸运的是,这可以绕过程序恢复位)。但最近我注意到,在启动 Chrome 时,它经常报告它被错误关闭,这确实支持了 Windows 在这方面存在缺陷的想法:
但是我从未见过完全无法通知正在运行的应用程序,这些应用程序无法通过上述记事本测试,在任何版本的 Windows 中都没有。作为信息,这是我当前的 Windows 版本,由 WinVer 报告(我听说过 2004 版本中存在一般问题,所以我暂时不会转向该版本):