【问题标题】:How to hook NTShutdownSystem in C# in order to differentiate between shutdown and reboot如何在 C# 中挂钩 NTShutdownSystem 以区分关机和重启
【发布时间】:2012-05-30 09:21:49
【问题描述】:

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

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

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

【问题讨论】:

  • 我喜欢这个问题,几个月前我不得不做类似的事情并且基本上放弃了:/会对答案非常感兴趣
  • 你知道方法是否被用户进程调用吗?鉴于我倾向于不使用的函数名称?

标签: c# hook shutdown reboot shutdown-hook


【解决方案1】:

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

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

这不是一件小事,但已经编写了一些框架来帮助尝试使用托管代码(例如 C#)hook routines like this

下一个要问的问题是你为什么在乎?

edit NTShutdownSystem 在关机过程中很晚才被调用 - 那时您可能没有 UI,也无法做任何事情。我建议拦截ExitWindowsExInitiateShutdownInitiateSystemShutdownInitiateSystemShutdownEx - 我不知道其中一些是否被另一个调用,但你应该只记录原因,然后对原因做出反应您的标准应用程序的WM_QUERYENDSESSION 代码。

【讨论】:

  • 嗨,如果用户注销(系统在 lparam 中设置一个值)或关闭,我确实会收到来自 WM_QUERYENDSESSION 的通知,但是当执行关闭时,如果系统没有收到通知重新启动或完全关闭。我肯定需要知道它,因为我确实运行了一个关闭脚本,该脚本需要根据用户关闭或重新启动而有所不同。
  • 如果你想要这些信息,你将不得不挂钩例程。我没有任何示例代码,因为挂钩是一项非常重要的任务,其中没有一个是脚手架。
  • 最后一件事 - NTShutdownSystem 的调用发生在关机过程的后期 - 你可能不会留下任何 UI。您最好拦截 ExitWindowsEx 或 InitiateShutdown 或类似
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-18
  • 2021-02-13
相关资源
最近更新 更多