如何在 C# 中挂接 NTShutdownSystem 以区分关机和重新启动

本文关键字:关机 重新启动 NTShutdownSystem | 更新日期: 2023-09-27 18:35:48

不幸的是

,当您收听WM_QUERYENDSESSION时,如果用户请求重新启动或关机,则不会获得信息。这确实是一个糟糕的设计,但这就是Windows的方式,所以我正在考虑将调用挂接到NTShutdownSystem,它得到一个参数,告诉系统执行重新启动或关闭。

问题是:如何在 C# 中实际实现这一点?我想获得某种钩子,我可以用来确定传递给NTShutdownSystem的参数,然后保存该信息。之后,我想按照用户想要的方式调用"真正的"NTShutdownSystem。

您有任何示例代码来说明这一点吗?

如何在 C# 中挂接 NTShutdownSystem 以区分关机和重新启动

WM_QUERYENDSESSION没有给出关机原因的原因是用户当时可能只是注销,而不是关闭系统。

这通常属于内核级挂钩的范畴,通常不被认为是一件好事,因为它会影响系统的稳定性。它们中的大多数都是用 C 或 C++ 编写的,并且通常需要付出很多努力才能在所有正在执行的程序中执行钩子 - 例如在程序加载时钩接例程。

这不是一件小事,但是已经编写了一些框架来帮助尝试使用托管代码(例如 C#)钩住这样的例程。

下一个要问的问题是你为什么关心?

编辑 NTShutdown系统在关机过程中很晚才被调用 - 此时您可能没有 UI,也无法执行任何操作。我建议拦截 ExitWindowsEx、InitiateShutdown、InitiateSystemShutdown 和 InitiateSystemShutdownEx - 我不知道其中一些是否被另一个调用,但您可能应该只记录原因,然后在标准应用程序的WM_QUERYENDSESSION代码中对原因做出反应。