Запис повідомлень в журнал подій Windows на Delphi (исходники), Різне, Програмування, статті

Додаток може записувати повідомлення в журнал використовуючи такі функції WinAPI. Детальний опис параметрів цих функцій міститься в документації до API. RegisterEventSource – Відкриває handle для доступу до журналу на локальної або віддаленої машині. ReportEvent – Власне записує повідомлення. Для запису повідомлень в журнал у спрощеній манері просто зробіть виклик RegisterEventSource з ім’ям машини (UNC), в журнал якій ви хочете помістити повідомлення (nil для локальної машини), і ім’ям події. Ім’я події це зазвичай назва програми, але може бути щось більш інформативним. Як тільки джерело подій зареєстрований, можна записувати події за допомогою ReportEvent з handle, який повернула RegisterEventSource .


Приклад:







VAR EventLog:THandle;
EventLog:=RegisterEventSource(nil,PChar(“MyApplication”));
VAR MyMsg:Array[0..2] of PChar;
MyMsg[0]:=”A test event message”; ReportEvent(EventLog,EVENTLOG_INFORMATION_TYPE,0,0,nil,1,0,@MyMsg,nil);


Однак текст повідомлення, записаного в журнал буде випереджене текстом: “The description for Event ID (0) in Source (MyApplication) cannot be found. The local computer may not have necessary registry information or message DLL files to display messages from a remote computer. The following information is part of the event: “(Не знайдено опис для події з кодом (0) в джерелі (MyApplication ). Можливо, на локальному комп’ютері немає потрібних даних в реєстрі або файлів DLL повідомлень для відображення повідомлень віддаленого комп’ютера. У записі події міститься наступна інформація 🙂 (Зауваження: Це повідомлення специфічно для Windows 2000і може трохи відрізнятися на інших версіях). Для запобігання появи цього тексту необхідно внести до реєстру деякі ключі, як показано нижче, і визначити рядкові ресурси (це може бути виконано будь-яким компонентом вашої програми, не обов’язково додатком, що буде записувати події). Відповідні записи реєстру описані нижче.


Приклади коду припускають, що строкові ресурси і категорії розташовані в тому ж виконуваному файлі, який містить програму, що записує події. Ключі категорій є опціональними. Сенс цих ключів реєстру і строкових ресурсів у тому, що журнал подій використовує рядок, а додаток записує в журнал у вигляді форматованого аргументу, і журналу необхідно знати, де знаходиться описувач формату для цього рядка. Крім того, в журналі може зберігатися інформація про категорію події, корисна для перегляду подій. Це зручніше, ніж просто відображати безліч однотипний подій “Ні”. Самий простий визначник формату це% 1, який просто передасть в журнал вхідні рядок. Для більш детального вивчення визначників формату см. API документацію для FormatMessage .

Ключі реєстру

Створіть наступний ключ реєстру: HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesEventlogApplication Ім’я програми AppName повинно співпадати з ім’ям джерела, використаного при виклику RegisterEventSource , Тому що переглядач подій буде використовувати це ім’я для відшукування подій. Створіть наступні ключі:
























Ім’я ключа

Тип

Опис


CategoryCount


(Optional)


Integer


Кількість категорій подій, які ви збираєтеся використовувати. (Це максимальна величина, і не буде проблем, якщо не всі категорії насправді будуть застосовуватися).


CategoryMessageFile


(Optional)


String


Файл, що містить ресурси рядків категорій.


EventMessageFile


String


Файл, що містить ресурси рядків подій.


TypesSupported


Integer


Допустимі типи подій.


Приклад коду для створення необхідних записів в реєстрі:







VAR


Reg:TRegistry;


RegKey:String;


AppPath:String;


AppName:String;


NumCategories:Integer;


Begin


Reg:=TRegistry.Create;


Try


AppPath:=Application.ExeName;


AppName:=”MyApplication”;


NumCategories:=2;


RegKey:= Format(“SYSTEMCurrentControlSetServicesEventLogApplication%s”,[AppName]);


Reg.RootKey:=HKEY_LOCAL_MACHINE;


Reg.OpenKey(RegKey,True);


Reg.WriteString (“CategoryMessageFile”, AppPath); / / Власне ім’я


Reg.WriteString (“EventMessageFile”, AppPath); / / Власне ім’я


Reg.WriteInteger (“CategoryCount”, NumCategories); / / Максимальна кількість категорій


Reg.WriteInteger (“TypesSupported”, EVENTLOG_SUCCESS or EVENTLOG_ERROR_TYPE or EVENTLOG_WARNING_TYPE or EVENTLOG_INFORMATION_TYPE); / / Дозволяємо всі типи


Reg.CloseKey;


EventLog:=RegisterEventSource(nil,PChar(AppName));


Finally


Reg.Free;


End; //try..finally


End;


Повідомлення та ресурси категорій


Інформація, що міститься в реєстр вищенаведеним кодом, інформує журнал подій про те, де шукати рядки подій і категорій, грунтуючись на імені джерела, яке використовує додаток для запису в журнал. І, як ми вже говорили, щоб журнал подій шукав ці рядки в нашому виконуваному файлі, нам потрібно включити ці рядкові ресурси в наш файл. Цей процес складається з наступних кроків:





Є багато прикладів з написання. mc файлів в Windows SDK і на різних сайтах, включаючи MSDN, однак документація не досить проста, тому наводимо мінімально достатня опис для створення файлу таблиці повідомлень:







;//Example Message source file exmess.mc


MessageId=0


Language=English


%1


MessageId=1


Language=English


Category1


MessageId=2


Language=English


Category2


Рядки, що починаються з ;/ / є коментарями і не компілюються. Цей приклад містить три строкових ресурсу – один визначник формату повідомлення і дві категорії, хоча файл може містити тільки перший ресурс. Кожен ресурс відділений однієї окремої точкою на рядку, так само, як і в кінці файлу. Якщо в кінці файлу відсутній переклад рядка після крапки, то файл не буде скомпільований.


Перший рядок кожного ресурсу є MessageID (index), за допомогою якого додаток буде звертатися до рядка. Наступний рядок вказує мову ресурсу. В нашому випадку “English” – означає international English, мову за замовчуванням для всіх Windows платформ. Інформацію по багатомовним ресурсів см. в довідці до компілятору ресурсів. Останній рядок визначає власне текст повідомлення. У разі ресурсу 0, рядок буде “% 1”, що означає, що передається сама рядок. Якщо, наприклад, потрібен префікс повідомлення “An Event Message” (Повідомлення події), то рядок матиме вигляд: “An Event Message% 1”. Більш повний опис форматів див API довідці по FormatMessage і компілятору ресурсів. Ресурси категорій не вимагають форматованих аргументів. Як видно в прикладі, ми визначили дві категорії “Category 1” і “Category 2”. Наступний етап – компіляція. mc файлу при допомоги Microsoft message compiler (mc. exe), який можна взяти у Microsoft (входить до складу Platform SDK). Наш приклад, що має ім’я “exmess. Mc” може бути скомпільований з командного рядка таким чином:







Mc exmess.mc


В результаті отримуємо три файли: exmess. rc, bin 00001. msg і exmess. h. emess. h може бути використаний як заголовний файл для звернення до ресурсів за їх символічним іменам, якщо такі зазначені (У нашому прикладі немає). . bin файл це відкомпільований бінарний ресурс з повідомленнями,. rc це файл ресурсів Windows . Він може бути откомпилирован в Delphi   . res файл за допомогою brcc 32. exe – компілятора ресурсів Delphi  або просто доданий в проект за допомогою project manager, і тоді Delphi   автоматично його відкомпілює при компіляції проекту (build).


Запис подій з категоріями.


Тепер наше додаток має ресурси і необхідні записи в реєстрі або код, який їх внесе. Значить, додаток може записувати події в журнал без повідомлення про відсутність ресурсів і з додатковим індексом категорії події:







VAR EventLog: THandle;
EventLog:=RegisterEventSource(nil,PChar(“MyApplication”));
VAR MyMsg:Array[0..2] of PChar;
MyMsg[0]:=”A test event message”;
ReportEvent(EventLog, EVENTLOG_INFORMATION_TYPE,1,0,nil,1,0,@MyMsg,nil);


Вищенаведений код запише подія в журнал з текстом “A test event message” і, тому що 1 слід за параметром EventLogType, це буде подія категорії “Category 1”. Це досягнуто зазначенням 0 в якості ідентифікатора події, який відповідає определителю формату в ресурсі 0 (“% 1”). В результаті текст повідомлення події буде переданий без зміни. Точно так же, категорія вказана 1, що відповідає “Category 1” в нашому ресурсі 1. Журнал подій підтримує “живий зв’язок” з файлами повідомлень і категорій, зазначених у реєстрі, що означає, що коли користувач захоче переглянути журнал, переглядач подій отримає доступ до файлів ресурсів для детального відображення подій. Це також означає, що якщо ви створите безліч подій, за допомогою вказаного файлу ресурсів, і, потім, змініть значення у файлі ресурсів і справите оновлення (refresh) в переглядачі подій, тексти подій і номери категорій так само зміняться відповідно до ресурсами. Точно так само, якщо файл ресурсів раптом буде видалений або записи в реєстрі будуть знищені або пошкоджені, то журнал не зможе отримати доступ до ресурсів, і відобразить повідомлення з помилкою у вигляді префікса події, як було описано на початку статті. В цьому випадку замість номера категорії події буде відображений індекс категорії.

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*