-1

我正在尝试为关闭 Windows 系统的代码开发一个简单的测试套件。要求是以编程方式确定系统在关闭之前是否实际收到了关闭调用(以将此结果进一步传递给测试套件)以及精确的关闭启动时间。

到目前为止,我已经尝试了几种不同的方法,但似乎都不令人满意:

1) 监控和捕获 WM_QueryEndSession 调用

缺点:基本上,这个调用通常用于通知正在运行的应用程序和交互用户系统关闭。但是,此调用可能不适用于无响应的应用程序或服务。或者实际关闭可能会延迟到无响应的服务终止并且应用程序被系统关闭,即使调用以正确的状态退出。

2) Windows 事件日志 可以开发一个程序来读取 Windows 事件日志。该程序将需要一些时间来扫描事件日志并验证是否记录了相关消息。但看起来这需要一些时间,并且在系统启动事件日志记录服务关闭并进一步关闭之前可能无法完成。此外,在系统关闭期间运行程序似乎并不可靠。

3) 简单地 ping 计算机以确保网络适配器已与网络断开连接。这不是关闭过程中采取的第一个动作,并且可能会因无响应过程和其他原因而显着延迟。

在系统关闭之前,有什么可靠的方法可以捕获对系统的关闭调用?

4

1 回答 1

0

老实说,我的大脑在尖叫。整个想法似乎有缺陷。这听起来像是在拼命尝试解决一个完全不同的问题的症状。此外,超出某些界限的测试通常是不明智的,而且有充分的理由:它使事情变得过于复杂,以至于实际上不值得付出努力。例如,在您正在测试关机的这种情况下:

  • 你真的要在测试中关机吗?
  • 其他不想让您现在关闭的应用程序
  • 如果您确实关闭了,您测试关闭的应用程序将与系统的其余部分一起关闭。
  • 关机后会自动重启吗?
  • 如果您使用关闭选项自动重启 - 这是否与生产场景相同?
  • 也许您需要适当的断电和 LAN 唤醒来执行远程重启以进行更真实的测试?
  • 或者您可能想在不实际关闭的情况下测试关闭命令?
    • 问题是,一旦您发送关闭命令(成功),Windows 就会开始关闭。
    • 您可以中止关闭,但到那时其他应用程序可能已响应请求而关闭(不是非常友好的行为)。

在这种情况下,将接口模拟到有问题的边界通常更合适。然后您只需测试与模拟的交互是否正确。

尽管如此,我仍然担心您正在尝试解决不同问题的症状。

您说:“某些 Windows 部署存在差异(但并非全部)”。
您是否确定了差异的根本原因?如果您的应用程序应该自动发出关闭命令,它可能会失败的原因有很多:

  • 应用程序可能尚未运行。
  • 可能存在阻止它进行必要调用的错误。
  • 它可能已经进行了调用,但 Windows 可能出于某种原因拒绝了它(希望您正在检查 API 调用的返回值?)(权限、远程会话、操作系统处于其他状态——谁知道呢?)。
  • 现在,即使调用返回成功结果,仍然可以停止关机。(顺便说一句,你说你需要知道启动时间。就是这样!这是关机开始的时间。将当前时间写入注册表中的文件 - 无论你喜欢什么。
  • 即使考虑到上述所有情况,任何应用程序都可以中止关闭过程。因此,即使您关闭系统的代码已经过彻底测试,并且运行良好 - 其他一些完全不相关的应用程序也可以转身说:“关闭时不,嘿!” - 系统继续运行....

回到“不同问题的症状”......你所说的一些事情(检查事件日志,关注时间,说:“如果关闭调用被发出给系统”)建议你试图事后找出“是否发出了关机命令”?

这听起来不像是一个测试问题——这听起来像是一个日志记录问题。

也许您想测试这个非常重要的日志记录是否正确发生?
这让我直接回到:而是模拟 Windows API 调用,并测试您与记录在案的 API 的交互是否正确

如果我没有劝阻你嘲弄疯狂之神...

您提到了监视WM_QueryEndSession的应用程序/服务没有响应的缺点。但是,您并不真正关心其他应用程序。您只需要一个应用程序,即您的应用程序。如有必要,一个小型简单的独立监控实用程序。当它收到消息时 - 将其连同原因一起记录下来。(当然,仍然不能保证关机会完成。)

您可以更进一步,您的监控应用程序可以使用SetProcessShutdownParameters函数成为通知关闭的第一个进程。当然,如果中止关闭,您的监控实用程序将不再运行,需要重新启动。(我有没有提到疯狂和精神错乱?
或者,将其设置为最后一次关闭,允许您在更接近实际关闭的时间采取一些行动(如果它确实关闭)。

您对阅读事件日志的担忧是因为在系统关闭时它可能太慢而无法完成。为什么您甚至想在关机期间阅读它?(或者这种疯狂已经占据了上风?)当磁盘无所作为时,数据不太可能流失。如果需要,请在重新启动时阅读。但首先阅读Shutdown Event Tracker

最后,不是(或除此之外)监听WM_QueryEndSession,而是监听WM_EndSession。在某些情况下,前者不会被发送。但据我所知,后者应该总是被发送。

我有提到疯狂吗?...也许是精神错乱。...我知道我提到了疯人斌。... 什么谁为什么什么时候怎么样?......他们在我的脑海里!
疯狂结束。

于 2013-09-08T23:39:14.680 回答