Я пытаюсь записать EventData (например, C Struct) в журнал событий приложения, используя «EventWrite». Я не вижу журналов, записанных в EventLog (приложение) Я использую приведенный ниже файл sprovider.mc.
MessageIdTypedef=DWORD
SeverityNames=(
Success=0x0:STATUS_SEVERITY_SUCCESS
Informational=0x1:STATUS_SEVERITY_INFORMATIONAL
Warning=0x2:STATUS_SEVERITY_WARNING
Error=0x3:STATUS_SEVERITY_ERROR
)
FacilityNames=(
System=0x0:FACILITY_SYSTEM
Runtime=0x2:FACILITY_RUNTIME
)
MessageId=0x0002
Severity=Error
Facility=Runtime
SymbolicName=MSG_RUNTIME_ERROR
Language=English
This is a runtime error message
.
Создание ресурсной DLL
mc -U sprovider.mc
rc sprovider.rc
link -dll -noentry -out:sprovider.dll sprovider.res /MACHINE:X64
И мой файл манифеста выглядит следующим образом:
<instrumentationManifest
xmlns = "http://schemas.microsoft.com/win/2004/08/events"
xmlns:win = "http://manifests.microsoft.com/win/2004/08/windows/events"
xmlns:xs = "http://www.w3.org/2001/XMLSchema"
>
<instrumentation>
<events>
<provider name = "evtlog" guid = "{78A1B3DE-42A7-4111-85B2-8D199812EDDF}" symbol = "MSG_RUNTIME_ERROR"
resourceFileName = "c:\\windows\\system32\\evtlog.dll"
messageFileName = "c:\\windows\\system32\\evtlog.dll">
<events>
<event symbol = "MSG_RUNTIME_ERROR" value = "2" version = "0" level = "win:Error" template = "MyEventTemplate"/>
</events>
<templates>
<template tid = "MyEventTemplate">
<data name = "Message" inType = "win:UnicodeString"/>
<data name = "UserName" inType = "win:UnicodeString"/>
</template>
</templates>
</provider>
</events>
</instrumentation>
</instrumentationManifest>
я бегу wevtutil в evnt.man Предупреждение. Файл ресурсов поставщика издателя не содержит ресурса метаданных. Обязательно свяжите файл .bin, созданный компилятором сообщений, с указанный двоичный файл.
имя_ресурса: c:\windows\system32\sprovider.dll
Я использую код Win32, как показано ниже, для записи событий.
#include <Windows.h>
#include <wchar.h>
#include <evntprov.h>
#include <iostream>
#include "evtlog.h"
using namespace std;
// Define the provider GUID
static const GUID MyProviderGuid =
{ 0x78a1b3de, 0x42a7, 0x4111, { 0x85, 0xb2, 0x8d, 0x19, 0x98, 0x12, 0xed, 0xdf } };
int wmain() {
// Register the event provider
REGHANDLE hProvider = NULL;
if (EventRegister(&MyProviderGuid, NULL, NULL, &hProvider) != ERROR_SUCCESS) {
// Handle the error
std::cout << GetLastError();
return 1;
}
// Sample structured data
struct MyEventData {
WCHAR Message[MAX_PATH];
WCHAR UserName[MAX_PATH];
};
MyEventData eventData = { L"Sree", L"This is a test message" };
// Event data descriptors
EVENT_DATA_DESCRIPTOR dataDescriptors[2];
EventDataDescCreate(&dataDescriptors[0], eventData.Message, (ULONG)(MAX_PATH));
EventDataDescCreate(&dataDescriptors[1], eventData.UserName, (ULONG)(MAX_PATH));
// Define the event descriptor
EVENT_DESCRIPTOR eventDescriptor;
EventDescCreate(&eventDescriptor, MSG_RUNTIME_ERROR, 0, FACILITY_RUNTIME, STATUS_SEVERITY_ERROR, 0, 0, 0);
BOOL bEnabled = EventEnabled(hProvider, &eventDescriptor);
std::cout << std::endl << "Enabled:" << bEnabled;
// Write the event
if (EventWrite(hProvider, &eventDescriptor, 2, dataDescriptors) != ERROR_SUCCESS) {
// Handle the error
std::cout << GetLastError();
return 1;
}
// Unregister the event provider
EventUnregister(hProvider);
return 0;
}
Исполняемый файл, созданный примерно из кода C, не может ничего записать в журнал. Пожалуйста, дайте мне знать, чего мне здесь не хватает.
Спасибо @YangXiaoPo-MSFT, я прочитал их, но так и не смог найти недостающий шаг для записи в журнал событий.
1. Ваш eventDescriptor отличается от заголовка, созданного mc.exe. Включите сгенерированный заголовок, чтобы использовать поставщика. 2. Как сказано в EventWrite: если это событие не фиксируется ни в одном сеансе трассировки, эта функция ничего не сделает и вернет ERROR_SUCCESS. и Чтобы снизить влияние на производительность событий, которые не записываются ни одним сеансом трассировки, вы можете вызвать EventEnabled, чтобы определить, записывает ли какой-либо сеанс трассировки ваше событие, прежде чем подготавливать данные и вызывать EventWrite.
Привет @YangXiaoPo-MSFT! Большое спасибо за помощь. Я попытался вызвать EventDescCreate(&eventDescriptor, MSG_RUNTIME_ERROR, 0, FACILITY_RUNTIME, STATUS_SEVERITY_ERROR, 0, 0, 0); Я все еще вижу, что EventEnabled возвращает False. Я использую эти константы из файла заголовка, предоставленного файлом mc. Я обновил код исходного сообщения.





По данным EventWrite,
Если ни один сеанс трассировки не записывает это событие, эта функция подойдет. ничего и вернуть ERROR_SUCCESS.
Итак, я начал сеанс трассировки с Примера создания сеанса и включения поставщика на основе манифеста или классического поставщика. Все работает нормально.
Также см. Реализация инструментов ETW и https://github.com/jebidiah-anthony/Windows-Event-Forwarder/blob/master/Creating%20Custom%20Logs.md для получения дополнительной информации.
Обновлять: Как говорит Определение каналов:
События можно записывать в каналы журнала событий, файлы журнала трассировки событий, или оба. Канал — это, по сути, приемник, который собирает события. Если целевая аудитория ваших мероприятий использует потребителей событий, таких как Windows Event Viewer, вам необходимо определить новые каналы для сбора события или импортируйте существующий канал, определенный другим провайдером.
Привет @YangXiaoPo-MSFT! Большое спасибо за помощь. Я очень ценю ваше время и усилия, чтобы ответить на мои вопросы. После запуска сеанса мой EventEnabled прошел успешно. Еще раз спасибо.
Попробуйте образец документа о Трассировке событий на основе манифеста . Также см. Написание манифеста инструментария для получения дополнительной информации.