This commit is contained in:
Zengtudor 2025-06-07 10:04:03 +08:00
parent 3ce5ae72a2
commit 4e358ea37d
2 changed files with 243 additions and 1 deletions

View File

@ -17,3 +17,4 @@ find_package(webview REQUIRED)
add_executable(${PROJECT_NAME} ${SRC_CPP})
target_link_libraries(${PROJECT_NAME} PRIVATE webview::core Wevtapi)
target_link_options(${PROJECT_NAME} PRIVATE -static)

View File

@ -1,3 +1,244 @@
int main(){
#include <fstream>
#include <iostream>
#include <ostream>
#include <string>
#include <windows.h>
#include <sddl.h>
#include <stdio.h>
#include <winevt.h>
#include <winnls.h>
// #pragma comment(lib, "wevtapi.lib")
#define ARRAY_SIZE 10
#define TIMEOUT 1000 // 1 second; Set and use in place of INFINITE in EvtNext call
DWORD PrintResults(EVT_HANDLE hResults);
DWORD PrintEvent(EVT_HANDLE hEvent); // Shown in the Rendering Events topic
#include <iostream>
#include <string>
#include <windows.h>
#include <sddl.h>
#include <stdio.h>
#include <winevt.h>
#pragma comment(lib, "wevtapi.lib")
#define ARRAY_SIZE 10
#define TIMEOUT 1000 // 1 second
DWORD PrintResults(EVT_HANDLE hResults);
DWORD PrintEvent(EVT_HANDLE hEvent);
#include <iostream>
#include <string>
#include <windows.h>
#include <sddl.h>
#include <stdio.h>
#include <winevt.h>
#pragma comment(lib, "wevtapi.lib")
#define ARRAY_SIZE 10
#define TIMEOUT 1000 // 1 second
DWORD PrintResults(EVT_HANDLE hResults);
DWORD PrintEvent(EVT_HANDLE hEvent);
// 检查是否以管理员权限运行
bool IsAdmin() {
BOOL isAdmin = FALSE;
SID_IDENTIFIER_AUTHORITY ntAuthority = SECURITY_NT_AUTHORITY;
PSID adminGroup;
if (AllocateAndInitializeSid(&ntAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &adminGroup)) {
if (!CheckTokenMembership(NULL, adminGroup, &isAdmin)) {
isAdmin = FALSE;
}
FreeSid(adminGroup);
}
return isAdmin;
}
// 获取错误消息字符串
std::wstring GetErrorMessage(DWORD errorCode) {
LPWSTR errorMsg = NULL;
DWORD size = FormatMessageW(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, errorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPWSTR)&errorMsg, 0, NULL
);
std::wstring message = (size > 0) ? std::wstring(errorMsg, size) : L"未知错误";
if (errorMsg) LocalFree(errorMsg);
return message;
}
int main(void)
{
// 设置控制台为UTF-8模式解决中文显示问题
SetConsoleOutputCP(CP_UTF8);
// 检查管理员权限
if (!IsAdmin()) {
std::wcout << L"警告: 程序未以管理员权限运行,可能无法访问系统事件日志。\n";
std::wcout << L"请右键点击程序并选择'以管理员身份运行'。\n\n";
}
DWORD status = ERROR_SUCCESS;
EVT_HANDLE hResults = NULL;
WCHAR pwsPath[MAX_PATH];
LPWSTR pwsQuery = L"*";
// 展开环境变量
ExpandEnvironmentStringsW(
L"%SystemRoot%\\System32\\Winevt\\Logs\\Microsoft-Windows-TerminalServices-RemoteConnectionManager%4Operational.evtx",
pwsPath,
MAX_PATH
);
std::wcout << L"尝试打开事件日志文件: " << pwsPath << L"\n";
// 使用EvtQueryFilePath标志查询文件
hResults = EvtQuery(NULL, pwsPath, pwsQuery, EvtQueryFilePath | EvtQueryReverseDirection);
if (NULL == hResults)
{
status = GetLastError(); // 获取错误代码
std::wcout << L"EvtQuery失败错误代码: " << status << L"\n";
std::wcout << L"错误描述: " << GetErrorMessage(status) << L"\n";
// 获取扩展错误信息
DWORD extendedStatusSize = 0;
EvtGetExtendedStatus(NULL, NULL, &extendedStatusSize);
if (extendedStatusSize > 0)
{
std::wstring extendedStatus;
extendedStatus.resize(extendedStatusSize);
if (EvtGetExtendedStatus(
extendedStatusSize,
&extendedStatus[0],
&extendedStatusSize
))
{
std::wcout << L"扩展错误信息: " << extendedStatus << L"\n";
}
}
goto cleanup;
}
std::wcout << L"成功打开事件日志文件\n";
std::wcout << L"开始查询事件...\n";
if (ERROR_SUCCESS == PrintResults(hResults)) {
std::wcout << L"查询完成\n";
} else {
std::wcout << L"查询过程中发生错误\n";
}
cleanup:
if (hResults)
EvtClose(hResults);
std::wcout << L"程序已完成\n";
system("pause"); // 保持控制台窗口打开
std::wcout<<std::flush<<'\n';
return 0;
}
// Enumerate all the events in the result set.
DWORD PrintResults(EVT_HANDLE hResults)
{
DWORD status = ERROR_SUCCESS;
EVT_HANDLE hEvents[ARRAY_SIZE];
DWORD dwReturned = 0;
while (true)
{
// Get a block of events from the result set.
if (!EvtNext(hResults, ARRAY_SIZE, hEvents, INFINITE, 0, &dwReturned))
{
if (ERROR_NO_MORE_ITEMS != (status = GetLastError()))
{
wprintf(L"EvtNext failed with %lu\n", status);
}
goto cleanup;
}
// For each event, call the PrintEvent function which renders the
// event for display. PrintEvent is shown in RenderingEvents.
for (DWORD i = 0; i < dwReturned; i++)
{
if (ERROR_SUCCESS == (status = PrintEvent(hEvents[i])))
{
EvtClose(hEvents[i]);
hEvents[i] = NULL;
}
else
{
goto cleanup;
}
}
}
cleanup:
for (DWORD i = 0; i < dwReturned; i++)
{
if (NULL != hEvents[i])
EvtClose(hEvents[i]);
}
return status;
}
DWORD PrintEvent(EVT_HANDLE hEvent)
{
DWORD status = ERROR_SUCCESS;
DWORD dwBufferSize = 0;
DWORD dwBufferUsed = 0;
DWORD dwPropertyCount = 0;
LPWSTR pRenderedContent = NULL;
// The EvtRenderEventXml flag tells EvtRender to render the event as an XML string.
if (!EvtRender(NULL, hEvent, EvtRenderEventXml, dwBufferSize, pRenderedContent, &dwBufferUsed, &dwPropertyCount))
{
if (ERROR_INSUFFICIENT_BUFFER == (status = GetLastError()))
{
dwBufferSize = dwBufferUsed;
pRenderedContent = (LPWSTR)malloc(dwBufferSize);
if (pRenderedContent)
{
EvtRender(NULL, hEvent, EvtRenderEventXml, dwBufferSize, pRenderedContent, &dwBufferUsed, &dwPropertyCount);
}
else
{
wprintf(L"malloc failed\n");
status = ERROR_OUTOFMEMORY;
goto cleanup;
}
}
if (ERROR_SUCCESS != (status = GetLastError()))
{
wprintf(L"EvtRender failed with %d\n", GetLastError());
goto cleanup;
}
}
{
std::basic_ofstream<wchar_t> os("log.txt");
os<<pRenderedContent<<'\n';
}
cleanup:
if (pRenderedContent)
free(pRenderedContent);
return status;
}