문제

Windows가 종료 될 때 WM_QueryEndsession 각 응용 프로그램에 대한 메시지. 따라서 Windows가 종료 될 때 쉽게 감지 할 수 있습니다. 그러나 컴퓨터가 전원 오프로 이동하는지 또는 Windows가 종료 된 후에 다시 시작되는지 알 수 있습니다.

MSDN의 문서를 고려할 때 특히 희망적이지 않습니다. WM_QUERYENDSESSION: "... 어떤 이벤트가 발생하는지 판단 할 수는 없지만 StackoverFlow의 누적 영리함은 결코 나를 놀라게하지 않습니다.

도움이 되었습니까?

해결책

에서 여기:

"hkcu software microsoft wind

약간의 원형 교차로 솔루션이지만 트릭을 수행해야합니다.

다른 팁

Windows 7 (및 아마도 Vista / 8 / Server)에서는 시스템 이벤트를 사용하여 Windows가 종료되고 컴퓨터 전원을 끄는지 또는 다시 시작하는지 추적 할 수 있습니다. Windows 7은 종료/재부팅이 시작될 때마다 (시작 메뉴에서 버튼을 클릭하거나) 시스템 로그, 소스 사용자 32, 이벤트 ID 1074에서 하나 또는 두 개의 이벤트를 작성합니다. 관리 도구에서 이벤트 뷰어를 엽니 다 (ID 1074 만 볼 수 있도록 시스템 로그를 필터링). 이 이벤트의 설명 (메시지)에는 종료 유형이 포함됩니다. 따라서이 유형의 가장 최근의 이벤트에 대한 설명을 구문 분석 할 수 있으며 (종료가 시작된 후) 필요한 단어 (종료, 재부팅/재시작)를 찾습니다.

전원 버튼을 사용하여 Windows를 우아하게 종료 할 때 이벤트에서 작성된 종료 유형을 보려고하지 않았지만 (일반적 으로이 기능을 비활성화합니다) 일부 사이트는 "종료"대신 "전원 끄기"유형을 표시한다고 제안합니다. 따라서 확실 해야하는 경우 확인하십시오. 또는 단순히 "재부팅"유형을 찾으십시오. 찾을 수없는 경우 "종료"유형이 가정됩니다.

Windows XP에서 내 경험에서 이벤트 1074는 셧다운/재부팅이 프로그래밍 방식으로 완료된 경우에만 기록됩니다 (예 : 프로그램 설치 중 또는 shutdown.exe 유틸리티를 사용하는 동안). 따라서 쉘 (Explorer)에서 시작된 종료를 등록하지는 않지만 다른 답변에서 제안 된 대로이 방법을 레지스트리의 값을 읽는 것과 결합 할 수 있습니다. 또한 WinXP에서 이벤트 1074의 메시지에는 실제 유형의 종료가 무엇이든 상관없이 "재시작"이라는 단어가 포함되어 있으므로 "종료 유형 :"필드를보아야합니다. "재부팅".

이와 관련하여 Windows가 어떤 이유로 Windows가 종료/재부팅에 실패 할 때마다 이벤트 ID 1073이 기록됩니다 (예 : 응용 프로그램이 WM_QueryEndsession에 대한 응답으로 종료되지 않는 경우). 이 경우 메시지에는 WinXP에서 "종료", "재부팅"또는 "전원 끄기"라는 단어도 포함됩니다. Win7의 경우이 유형의 이벤트는 셧다운과 재부팅 사이에 차이가 없기 때문에 우리의 경우 유용하지 않습니다. 그러나 WinXP의 경우 - 셧다운/재부팅을 가로 채어야하는 경우 일부 작업을 수행 한 다음 해당 종료 또는 재부팅 프로세스를 계속하십시오. 예상대로 작동해야합니다.

일반적으로 작동하는 트릭은 트랩하는 것입니다 WM_ENDSESSION 그리고 로그. 이제 시간을 추적하십시오. 시스템이 합리적인 erveroid (예 : 5 분) 내에 다시 등장하는 경우. 그런 다음 셧다운이 아닌 재부팅이었습니다.

아이디어: 시스템이 5 분 안에 다시 등장하면 진짜 사용자가 '종료'또는 '재부팅'을 클릭 한 경우 중요합니까?

셧다운을 감지 해야하는 경우 (그리고이를 수행해야 할 유일한 이유는 셧다운 대 재부팅 사이의 모호한 행동 소프트웨어 차이에 의존한다면) 조사 할 수 있습니다. 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