include <windows.h>
include <tchar.h>
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
HANDLE hEventLog = NULL;
DWORD dwReadFlags = EVENTLOG_BACKWARDS_READ | EVENTLOG_SEQUENTIAL_READ;
DWORD dwFilterFlags = EVENTLOG_FORWARDS_READ | EVENTLOG_SEEK_READ;
DWORD dwEventType = 0 | 2 | 1;
DWORD dwEventID = 1074; // 关机事件的Event ID
DWORD dwRecordOffset = 0;
DWORD dwBytesRead = 0;
PEVENTLOGRECORD pEventRecord = NULL;
// 打开系统日志
hEventLog = OpenEventLog(NULL, L"System");
if (hEventLog == NULL)
{
MessageBox(NULL, L"Failed to open system event log.", L"Error", MB_OK | MB_ICONERROR);
return 0;
}
// 从最新的记录开始向前遍历所有日志记录,找到最近的关机事件
while (ReadEventLog(hEventLog, dwReadFlags, 0, &pEventRecord, dwRecordOffset, 0, &dwBytesRead))
{
if (pEventRecord->EventType == dwEventType && pEventRecord->EventID == dwEventID)
{
WCHAR szMessage[1024] = { 0 };
SYSTEMTIME st;
FILETIME ft;
ULARGE_INTEGER uli;
// 将Event记录的时间戳转换为本地时间
memcpy(&ft, &pEventRecord->TimeGenerated, sizeof(ft));
uli.LowPart = ft.dwLowDateTime;
uli.HighPart = ft.dwHighDateTime;
uli.QuadPart -= 116444736000000000LL; // Windows Epoch (1601-01-01 00:00:00) to Unix Epoch (1970-01-01 00:00:00)
st.wYear = 1970;
st.wMonth = 1;
st.wDay = 1 + (WORD)(uli.QuadPart / 864000000000);
st.wHour = (WORD)((uli.QuadPart % 864000000000) / 36000000000);
st.wMinute = (WORD)((uli.QuadPart % 36000000000) / 600000000);
st.wSecond = (WORD)((uli.QuadPart % 600000000) / 10000000);
st.wMilliseconds = (WORD)((uli.QuadPart % 10000000) / 10000);
// 格式化提示信息
swprintf_s(szMessage, ARRAYSIZE(szMessage), L"The system was shut down on %04u-%02u-%02u %02u:%02u:%02u.%03u.",
st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
MessageBox(NULL, szMessage, L"Last shutdown time", MB_OK | MB_ICONINFORMATION);
break;
}
dwRecordOffset += dwBytesRead;
}
CloseEventLog(hEventLog);
return 0;
}
|