How to detect whether Windows is shutting down or restarting

前端 未结 4 1321
小蘑菇
小蘑菇 2020-12-01 13:04

I know that when Windows is shutting down, it sends a WM_QUERYENDSESSION message to each application. This makes it easy to detect when Windows is shutting down. However, is

4条回答
  •  情深已故
    2020-12-01 13:20

    Possible experimental solution for Windows7 could be the following. (I'm not sure if this works well with other localizations, therefore I would call it a workaround)

    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(
                        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 xPathEnum = xPathRefs;
    
                    EventLogPropertySelector logPropertyContext = new EventLogPropertySelector(xPathEnum);
                    IList 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();
            }
        }
    }
    }
    
    
    

    The following is an example of XML which is written to the event log when a PC is restarted:

    - 
    - 
       
      1074 
      4 
      0 
      0x80000000000000 
       
      90416 
      System 
      WIN7PC 
       
      
    - 
      C:\Windows\system32\winlogon.exe (WIN7PC) 
      WIN7PC 
      No title for this reason could be found 
      0x500ff 
      restart 
       
      WIN7PC\WIN7PCUser 
     FF00050000000000000000000000000000000000000000000000000000000000 
      
      
    

    提交回复
    热议问题