请问怎么获取Windows日志的常规内容,不是详细xml的那个内容
方法教你,代码自己写吧
参考示例 https://learn.microsoft.com/en-us/windows/win32/eventlog/receiving-event-notification
1. 获取到 EVENTLOGRECORD
2. 获取到EventSource, TCHAR* source = (TCHAR*)((BYTE*)eventrecord + sizeof(EVENTLOGRECORD))
3. 注册表读取 HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/EventLog/System/<EventSource名称>/EventMessageFile
4. 加载得到的多个DLL,LoadLibraryEx(dll名称, NULL, LOAD_LIBRARY_AS_IMAGE_RESOURCE | LOAD_LIBRARY_AS_DATAFILE)
5. FormatMessage传入DLL的handle,得到中间字符串,参考示例中的GetMessageString函数和调用它的地方
6. 中间字符串中的所有 %XXX,再调用FormatMessage得到字符串,替换掉。参考示例中的ApplyParameterStringsToMessage函数
7. 打印输出结果字符串
8. 卸载DLL
这是我的代码,就是把Windows日志改为syslog形式,但是现在缺少一个message内容,想获取那个内容描述不知道怎么获取啊
这是我的代码,就是把Windows日志转成syslog格式的内容进行打印,但是现在缺少一个内容,xml的那个不能作为内容啊
#include <windows.h>
#include <iostream>
#include <string>
//std::wstring wstrMessage((wchar_t*)((BYTE*)pEventLogRecord + pEventLogRecord->StringOffset))
using namespace std;
#define set_char 20000
int main()
{
LPVOID lpMsgBuf;
int set_num2 = 0;
DWORD dwRead, dwNeeded, dwThisRecord;
string Source;
time_t Time;
unsigned short ID;
EVENTLOGRECORD* pevlr;
char *Data = new char[set_char]; //缓冲区大小,如果太小读到的记录会少于windows日志
HANDLE Log = OpenEventLog(NULL, "System");//第一次参数表示本地计算机,第二个参数表示系统日志
if (Log == NULL)
{
cout << "==" << endl;
return 0;
}
GetOldestEventLogRecord(Log, &dwThisRecord);
int a = 0;
while (true)
{
if (a = ReadEventLog(Log, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ, 0, Data, set_char, &dwRead, &dwNeeded))
{
for (DWORD i = 0; i < dwRead;)
{
EVENTLOGRECORD* ptr = (EVENTLOGRECORD*)(Data + i);
Source = (TCHAR*)ptr + sizeof(EVENTLOGRECORD);//事件源
ID = (unsigned short)ptr->EventID;//事件ID
//&& Source != "EventLog"
/*if (Source != "Microsoft-Windows-Kernel-General")
{
i += ptr->Length;
continue;
}*/
struct tm SysStartupTime;//时间结构体
Time = ptr->TimeGenerated;//日期和时间
char buf[64]{ 0 };//用来存放时间
localtime_s(&SysStartupTime, &Time);//时间戳转化为格式时间
strftime(buf, _countof(buf), "%Y-%m-%d %H:%M:%S", &SysStartupTime);//格式化时间到缓冲区
char* pchar = (TCHAR*)ptr + sizeof(EVENTLOGRECORD);
pchar += (strlen(pchar) + 1);
string UserID = pchar;
string User;
pchar += strlen(pchar) + 1;
char Buffer[1024];
if (ptr->UserSidLength > 0)
{
char Name[64];
DWORD Length = sizeof(SID), Length1 = sizeof(Buffer);
SID_NAME_USE Type = SidTypeUser;
SID* sid = (SID*)(Data + ptr->UserSidOffset);
if (LookupAccountSid(NULL, sid, Name, &Length, Buffer, &Length1, &Type))
User = Name;
}
//cout << "---------------系统--------------" << endl;
//cout << "事件:";
string Type;
switch (ptr->EventType)
{
case 0: Type = "2"; break;
case 1: Type = "3"; break;
case 2: Type = "4"; break;
case 4: Type = "5"; break;
default:continue;
}
string str;
str += "<";
str += Type;
str += ">";
// str += "Time:";
str += buf;
str += " ";
// str += " Hostname:";
str += UserID;
str += " ";
// str += " APPNANME:";
str += (char*)(LPBYTE)ptr + sizeof(EVENTLOGRECORD);
str += ": ";
// str += " ID:";
str += to_string(ID);
str += " ";
// str += pchar;
if (ptr->DataOffset > ptr->StringOffset)
{
pchar = Data + i + ptr->StringOffset;
//printf("%s \n", pchar);
str += pchar;
for (short j = 0; j < ptr->NumStrings; j++)
{
pchar += strlen(pchar) + 1;
//cout << pchar << endl;
str += " ";
str += pchar;
}
}
if (ptr->NumStrings > 0)
{
for (WORD j = 0; j < ptr->NumStrings; j++)
{
if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, *((LPDWORD)((LPBYTE)ptr + ptr->StringOffset + sizeof(DWORD) * j)), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpMsgBuf, 0, NULL))
{
printf("Description: %s\n", (LPSTR)lpMsgBuf);
LocalFree(lpMsgBuf);
}
}
}
cout << str << endl;
//cout << "----------" << str << "-----------" << endl;
i += ptr->Length;
//cout << endl;
}
}
}
delete[] Data;
CloseEventLog(Log);
}
参考如下代码:
#include "stdafx.h"
#include <iostream>
using namespace std;
int execmd(char* cmd, char* result) {
char buffer[128]; // 缓冲区
FILE* pipe = _popen(cmd, "r"); // 管道
// 管道打开失败
if (!pipe){return 0;}
// 检测管道中的结束符,0表示没有结束
while(!feof(pipe)){
// 从管道中读取数据
if (fgets(buffer, 128, pipe)) {
// 拼接 char
strcat(result, buffer);
}
}
//关闭管道
_pclose(pipe);
return 1;
}
int main()
{
char result[0x7ffff] = ""; // 存放结果
// 获取命令行返回值(保险起见这里获取 300 条日志信息)
if (execmd("wevtutil qe System /c:300 /rd:true /f:text", result) == 1) {
cout << result << endl;
}
// 查找关键数据
string s = result;
while ((s.find("igfx")) != -1) {
cout << "找到了 igfx " << endl;
break;
}
system("pause");
return 0;
}
以下答案由GPT-4.0Plus大模型与博主A努力中.......共同编写:
在Windows系统中,有两种方式可以获取日志内容:
除此之外,Windows还提供了logman和PowerShell等日志管理工具,也可以用于查询和订阅Windows日志。但相比事件查看器和Wevtutil,它们的日志输出格式可能更为复杂,不太适合您要的“常规内容”。
原生方案,我这里也没测试ok,也许你可以去看看托管C++的封装。
方案1、Wevtutil.exe
https://www.cnblogs.com/LyShark/p/15019941.html
#include "stdafx.h"
#include <iostream>
using namespace std;
int execmd(char* cmd, char* result) {
char buffer[128]; // 缓冲区
FILE* pipe = _popen(cmd, "r"); // 管道
// 管道打开失败
if (!pipe){return 0;}
// 检测管道中的结束符,0表示没有结束
while(!feof(pipe)){
// 从管道中读取数据
if (fgets(buffer, 128, pipe)) {
// 拼接 char
strcat(result, buffer);
}
}
//关闭管道
_pclose(pipe);
return 1;
}
int main()
{
char result[0x7ffff] = ""; // 存放结果
// 获取命令行返回值(保险起见这里获取 300 条日志信息)
if (execmd("wevtutil qe System /c:300 /rd:true /f:text", result) == 1) {
cout << result << endl;
}
// 查找关键数据
string s = result;
while ((s.find("igfx")) != -1) {
cout << "找到了 igfx " << endl;
break;
}
system("pause");
return 0;
}
方案2、用托管C++项目(反正都是windows跑),用封装好的EventLog
EventLog^ log = gcnew EventLog();
log->Log = ("system");
EventLogEntryCollection^ myCollection = log->Entries;
for each (EventLogEntry^ test in myCollection)
{
Console::WriteLine(test->Message);
Console::WriteLine(test->TimeWritten);
}
具体步骤如下:
1.打开“事件查看器”(Event Viewer)。
2.在左侧窗格中选择“Windows日志”(Windows Logs)。
3.选择你想要查看的日志类型,如“应用程序”(Application)、“系统”(System)等。
4.在右侧窗格中,你将看到日志的列表。每个日志条目都包含时间戳、事件ID、级别、来源、描述等信息。
5.点击任意一条日志条目,你将看到该事件的详细信息,包括时间、级别、源、任务类别、关键字等。
6.如果你想导出日志内容,可以右键点击日志列表中的任意一个条目,选择“保存所有事件”(Save All Events),并选择要保存的文件格式和位置。
如有帮助,望采纳,谢谢!