与大多数“旧版”MSDN 页面一样,ReportEvent页面的信息太少,我无法理解它。我试过搜索,但找不到一个好的、干净、简单的函数用法示例。有人可以推荐一个吗?
4 回答
我最终使用了这个:
HANDLE eventLog;
WORD type;
const char* msg;
// ... snip ...
ReportEvent(eventLog, type, 0, 1, NULL, 1, 0, &LPCTSTR(msg), NULL);
似乎工作得很好。
好吧,这似乎是一个非常古老的线程,在这里寻找报告事件的一个很好的例子......但发现你没有收到任何回复......并且可能已经找到了解决方案。
您看到“未找到事件 ID”的原因是 EventViewer 无法加载/查找要为事件 ID 显示的文本资源。抱歉,如果最后一行听起来很怪异..但这是我对 EventLog 的理解:
-EventLogging有两个方面
- 向 EventLog 注册(或用其他术语创建 EventSource)
- 记录或写入事件日志
- 查看或读取日志
在事件日志中注册时,您只需指定一个 eventSource(标识该日志的任何名称)+ EventMessageFile、Category File 和 SupportedEventTypes。这里 EventMessageFile 指向一个包含您的消息描述/资源的 DLL/EXE。
当您记录一个事件时,您只需使用一些数据(例如 EventID、Category ID 和 EventData)来记录它。但是,当您使用任何 EventViewer(或 Windows eventVwr.exe)查看它时,查看器会读取您的事件,查找与您的 eventSource(由 EventMessageFile 指向)关联的 DLL/EXE,并从该 DLL/EXE 的资源部分呈现说明.
这个 DLL 只不过是一个使用 MessageCompiler 编译的简单资源文件,并包含一个“MessageTable”。这样做是为了提供特定于文化的事件记录
这就是原因,当您从 EventViewer 将日志导出为 XML/TXT 等时,它会询问您是要“带显示信息”还是“不带显示信息”保存它,以便您可以在执行此操作的计算机上查看它没有 EventMessageFile。
JFYI reg 条目位于:
HKLM\CurrentControlSet\System\Services\EventLog\Application
一个问题:如果您想知道 .Net 是如何做到的...,它只是通过提供一个名为 EventLogMessage.dll 的默认 EventMessageFile 来做到这一点(在 下找到%SYSTEMROOT%\Microsoft.Net\Framework\vXXXX\
)
我记得正确设置很痛苦——您需要使用消息编译器向您的应用程序添加消息——如果您跳过此操作,您将不会看到有用的消息,只有错误代码。以使用 ATL 创建 Windows NT 服务为例
示例 Windows Service C++,是一个向事件日志报告的 Windows 服务,您可以从https://code.msdn.microsoft.com/windowsapps/CppWindowsService-cacf4948获取代码 ,特别是以下函数(引用自 ServiceBase.cpp ) 可以
//
// FUNCTION: CServiceBase::WriteEventLogEntry(PWSTR, WORD)
//
// PURPOSE: Log a message to the Application event log.
//
// PARAMETERS:
// * pszMessage - string message to be logged.
// * wType - the type of event to be logged. The parameter can be one of
// the following values.
//
// EVENTLOG_SUCCESS
// EVENTLOG_AUDIT_FAILURE
// EVENTLOG_AUDIT_SUCCESS
// EVENTLOG_ERROR_TYPE
// EVENTLOG_INFORMATION_TYPE
// EVENTLOG_WARNING_TYPE
//
void CServiceBase::WriteEventLogEntry(PWSTR pszMessage, WORD wType)
{
HANDLE hEventSource = NULL;
LPCWSTR lpszStrings[2] = { NULL, NULL };
hEventSource = RegisterEventSource(NULL, m_name);
if (hEventSource)
{
lpszStrings[0] = m_name;
lpszStrings[1] = pszMessage;
ReportEvent(hEventSource, // Event log handle
wType, // Event type
0, // Event category
0, // Event identifier
NULL, // No security identifier
2, // Size of lpszStrings array
0, // No binary data
lpszStrings, // Array of strings
NULL // No binary data
);
DeregisterEventSource(hEventSource);
}
}