我知道,当Windows正在关闭时,它发送的 WM_QUERYENDSESSION 消息给每个应用程序。这可以很容易地在Windows正在关闭检测。然而,是否有可能知道,如果电脑要关机或正在准备重新启动Windows已经关机。

我不是特别乐观,考虑在MSDN文档有此说关于WM_QUERYENDSESSION:“......这是不可能的,以确定哪些事件正在发生,”但计算器累计聪明从来没有停止给我带来惊喜<。 / p>

有帮助吗?

解决方案

这里

  

可以读取来自DWORD值   “HKCU \软件\微软\的Windows \ CurrentVersion \ Explorer中\关机   设置”,以确定用户什么   最后从Shut选择向下   对话框。

迂回溶液的位,但它应该做的伎俩。

其他提示

在Windows 7中(可能也是在Vista / 8 /服务器),你可以使用系统事件跟踪的Windows是否关闭(和计算机电源关闭)或只是重新启动。每次关机/重启开始时间(通过任何方式 - 点击开始菜单按钮,或在程序上),Windows 7中写道:在系统日志中的一个或两个事件,源USER32,事件ID 1074你可以看到,如果记录这些事件您从管理工具(过滤系统日志只看到ID 1074)打开事件查看器。这些事件的说明(消息)包含关断型。所以,你可以分析最近的这种类型的事件的说明(关机开始后),找必要的字(关机,重启/重启)。

我没有尝试看看使用电源按钮正常关闭的Windows(我通常禁用此功能)时,写入事件关机类型,但一些网站的建议,它指出了“断电”型而非“关机” - 所以检查出来,如果你需要确定。或者干脆找一个“重启”型 - 如果它没有找到,那么“关机”型假设

在Windows XP中,从我的经验,事件1074被记录只有在关机/重启编程完成(例如在一个程序安装或使用shutdown.exe的实用程序)。因此,它不注册从壳(资源管理器)开始停产检修,但也许你就可以像在另一个答案建议阅读从注册表中的值,此方法结合起来。另外,请记住,在WinXP事件1074的消息包含单词“重启”不管真正的类型关机的是什么,所以你应该看看“关机类型:”字段,这将说明无论是“关机”或“重新启动”。

与此相关的,事件ID 1073被记录每当Windows无法关机/重启出于某种原因(例如,如果一个应用程序不允许关闭以WM_QUERYENDSESSION的响应)。在这种情况下该消息还将包含词作为“关断”,“重新启动”或“断电” - 在WinXP。对于Win7的这种类型的事件在我们的情况不太有用,因为它不会让关机和重启任何区别。但对于WinXP的 - 如果你只需要拦截关机/重启,执行一些操作,然后继续相应的关机或重启的过程 - 它应该按预期工作

这通常工作甲诀窍是陷阱WM_ENDSESSION和记录它。现在跟踪的时间。如果系统回来了一个合理的peroid内(如5分钟)。然后,这是重新启动,并不关闭。

创意:如果系统恢复后5分钟内,做它的真正的问题,如果用户点击 '关机' 或 '重启'

如果你真的需要检测关闭(和唯一的原因,我认为你需要做的是,如果你根据停机之间VS重启一个不起眼的行为差异的软件),你可以调查API hookingExitWindowsEx和相关的功能,但我不推荐这种方法。重新思考,如果你真的需要直接检测这一点。

有关的Windows7可能的实验方案可以是以下内容。 (我不知道这是否与其他本地化运作良好,因此我把它称为一种变通方法)

using System.Diagnostics.Eventing.Reader;

namespace MyApp
{
public class RestartDetector : IDisposable
{
    public delegate void OnShutdownRequsted(bool restart);
    public OnShutdownRequsted onShutdownRequsted;

    private EventLogWatcher watcher = null;

    public RestartDetector()
    {
        try
        {
            EventLogQuery subscriptionQuery = new EventLogQuery(
                "System", PathType.LogName, "*[System[Provider[@Name='USER32'] and (EventID=1074)]]");

            watcher = new EventLogWatcher(subscriptionQuery);

            // Make the watcher listen to the EventRecordWritten
            // events.  When this event happens, the callback method
            // (EventLogEventRead) is called.
            watcher.EventRecordWritten +=
                new EventHandler<EventRecordWrittenEventArgs>(
                    EventLogEventRead);

            // Activate the subscription
            watcher.Enabled = true;
        }
        catch (EventLogReadingException e)
        {
        }
    }

    public void EventLogEventRead(object obj, EventRecordWrittenEventArgs arg)
    {
        bool restart = false;
        try
        {
            // Make sure there was no error reading the event.
            if (arg.EventRecord != null)
            {
                String[] xPathRefs = new String[1];
                xPathRefs[0] = "Event/EventData/Data";
                IEnumerable<String> xPathEnum = xPathRefs;

                EventLogPropertySelector logPropertyContext = new EventLogPropertySelector(xPathEnum);
                IList<object> logEventProps = ((EventLogRecord)arg.EventRecord).GetPropertyValues(logPropertyContext);

                string[] eventData = (string[])logEventProps[0];

                foreach (string attribute in eventData)
                {
                    if (attribute.Contains("restart")) { restart = true; break; }
                }
            }
        }
        catch (Exception e)
        {
        }
        finally
        {
            if (onShutdownRequsted != null) { onShutdownRequsted(restart); }
        }   
    }

    public void Dispose()
    {
        // Stop listening to events
        if (watcher != null)
        {
            watcher.Enabled = false;
            watcher.Dispose();
        }
    }
}
}

下面是当PC重新启动信息被写入到事件日志XML的示例:

- <Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
- <System>
  <Provider Name="USER32" /> 
  <EventID Qualifiers="32768">1074</EventID> 
  <Level>4</Level> 
  <Task>0</Task> 
  <Keywords>0x80000000000000</Keywords> 
  <TimeCreated SystemTime="2015-12-15T11:10:43.000000000Z" /> 
  <EventRecordID>90416</EventRecordID> 
  <Channel>System</Channel> 
  <Computer>WIN7PC</Computer> 
  <Security UserID="S-1-5-21-1257383181-1549154685-2724014583-1000" /> 
  </System>
- <EventData>
  <Data>C:\Windows\system32\winlogon.exe (WIN7PC)</Data> 
  <Data>WIN7PC</Data> 
  <Data>No title for this reason could be found</Data> 
  <Data>0x500ff</Data> 
  <Data>restart</Data> 
  <Data /> 
  <Data>WIN7PC\WIN7PCUser</Data> 
 <Binary>FF00050000000000000000000000000000000000000000000000000000000000</Binary> 
  </EventData>
  </Event>
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top