تحديث سجل أحداث Windows إلى تطبيق Delphi 5
سؤال
أنا أبحث عن وسيلة (خالية من الألم إلى حد ما) لإضافة بعض دعم سجل أحداث تطبيقات Windows إلى تطبيق دلفي 5 القديم الصغير.نريد فقط أن يتم تسجيل الدخول عند بدء التشغيل أو إيقاف التشغيل أو فشل الاتصال بقاعدة البيانات وما إلى ذلك.
يبدو أن العديد من الحلول/المكونات التي رأيتها تشير إلى أننا سنحتاج إلى إنشاء ملف DLL للمورد والذي سيرتبط به Windows Event Log Viewer عند محاولة قراءة "الإدخالات" الخاصة بنا.على الرغم من أن هذا لا يبدو مرهقًا للغاية، أعتقد أنه شيء آخر يجب أخذه في الاعتبار إذا/عندما نقوم بتطوير التطبيق في المستقبل - سنحتاج إلى تحديث ملف DLL هذا.
في مرحلة ما في المستقبل، سنرغب في تحويل التطبيق إلى خدمة، ربما تكون مكتوبة في D2007.
فهل يمكن لأي شخص أن يوصي بطريق مناسب لإضافة الأحداث إلى سجل الأحداث في D5؟أبحث عن معيناستخدمنا هذا وكان بخير" التعليقات بدلاً من شبكة Google (التي يمكنني القيام بها بنفسي!) مجانًا أو مدفوعة الأجر، لا مانع حقًا - ولكن هناك شيء يمكنني ترحيله إلى D2007 في المستقبل وهو أمر مهم.
المحلول 4
وبفضل <م> J م> وردود بطرس، وحصلت على قانون بلدي الكتابة في سجل الأحداث على الفور. هناك ما هو أكثر قليلا القيام به، لا سيما إذا كنت تريد الأحداث لتظهر "لطيف" في سجل أحداث دون رسالة ويندوز القياسية من عدم التمكن من العثور على وصف (كما في الجزء السفلي من J م في مرحلة ما بعد)>.
وتابعت نصائح هنا لجعل DLL مناسبة والدخول إلى التسجيل، وبسرعة كبيرة وكان كل شيء تسويتها.
وهذا كله كان في Delphi5، كما في السؤال، ولكن رأيت شيئا يجعلني أعتقد أنه لن ينجح أيضا في D2007.
نصائح أخرى
ملخص:الكتابة إلى سجل أحداث Windows باستخدام دلفي
إذا كنت تكتب خدمة Windows وتحتاج إلى الكتابة إلى سجل أحداث Windows الخاص بالجهاز المحلي، فيمكنك الاتصالTService.رسالة السجل كما ذكر هنا.
//TMyTestService = class(TService)
procedure TMyTestService.ServiceStart(Sender: TService; var Started: Boolean);
begin
LogMessage('This is an error.');
LogMessage('This is another error.', EVENTLOG_ERROR_TYPE);
LogMessage('This is information.', EVENTLOG_INFORMATION_TYPE);
LogMessage('This is a warning.', EVENTLOG_WARNING_TYPE);
end;
بالنسبة لأي نوع آخر من التطبيقات، يمكنك استخدام ملف SvcMgr.TEventLogger غير موثقة helper لـ TService لكتابة سجل أحداث Windows الخاص بالجهاز المحلي كما هو مذكور هنا, هنا و هنا.
uses
SvcMgr;
procedure TForm1.EventLoggerExampleButtonClick(Sender: TObject);
begin
with TEventLogger.Create('My Test App Name') do
begin
try
LogMessage('This is an error.');
LogMessage('This is another error.', EVENTLOG_ERROR_TYPE);
LogMessage('This is information.', EVENTLOG_INFORMATION_TYPE);
LogMessage('This is a warning.', EVENTLOG_WARNING_TYPE);
finally
Free;
end;
end;
end;
يمكنك أيضًا استخدام Windows API تقرير الحدث وظيفة كما ذكر هنا و هنا.
لقد قمت بإنشاء فصل دراسي بسيط لتسهيل الأمر، إنه كذلك متاح على جيثب.
//----------------- EXAMPLE USAGE: ---------------------------------
uses
EventLog;
procedure TForm1.EventLogExampleButtonClick(Sender: TObject);
begin
TEventLog.Source := 'My Test App Name';
TEventLog.WriteError('This is an error.');
TEventLog.WriteInfo('This is information.');
TEventLog.WriteWarning('This is a warning.');
end;
//------------------------------------------------------------------
unit EventLog;
interface
type
TEventLog = class
private
class procedure CheckEventLogHandle;
class procedure Write(AEntryType: Word; AEventId: Cardinal; AMessage: string); static;
public
class var Source: string;
class destructor Destroy;
class procedure WriteInfo(AMessage: string); static;
class procedure WriteWarning(AMessage: string); static;
class procedure WriteError(AMessage: string); static;
class procedure AddEventSourceToRegistry; static;
end;
threadvar EventLogHandle: THandle;
implementation
uses Windows, Registry, SysUtils;
class destructor TEventLog.Destroy;
begin
if EventLogHandle > 0 then
begin
DeregisterEventSource(EventLogHandle);
end;
end;
class procedure TEventLog.WriteInfo(AMessage: string);
begin
Write(EVENTLOG_INFORMATION_TYPE, 2, AMessage);
end;
class procedure TEventLog.WriteWarning(AMessage: string);
begin
Write(EVENTLOG_WARNING_TYPE, 3, AMessage);
end;
class procedure TEventLog.WriteError(AMessage: string);
begin
Write(EVENTLOG_ERROR_TYPE, 4, AMessage);
end;
class procedure TEventLog.CheckEventLogHandle;
begin
if EventLogHandle = 0 then
begin
EventLogHandle := RegisterEventSource(nil, PChar(Source));
end;
if EventLogHandle <= 0 then
begin
raise Exception.Create('Could not obtain Event Log handle.');
end;
end;
class procedure TEventLog.Write(AEntryType: Word; AEventId: Cardinal; AMessage: string);
begin
CheckEventLogHandle;
ReportEvent(EventLogHandle, AEntryType, 0, AEventId, nil, 1, 0, @AMessage, nil);
end;
// This requires admin rights. Typically called once-off during the application's installation
class procedure TEventLog.AddEventSourceToRegistry;
var
reg: TRegistry;
begin
reg := TRegistry.Create;
try
reg.RootKey := HKEY_LOCAL_MACHINE;
if reg.OpenKey('\SYSTEM\CurrentControlSet\Services\Eventlog\Application\' + Source, True) then
begin
reg.WriteString('EventMessageFile', ParamStr(0)); // The application exe's path
reg.WriteInteger('TypesSupported', 7);
reg.CloseKey;
end
else
begin
raise Exception.Create('Error updating the registry. This action requires administrative rights.');
end;
finally
reg.Free;
end;
end;
initialization
TEventLog.Source := 'My Application Name';
end.
تقرير الحدث يدعم كتابة إدخال سجل إلى سجل الأحداث الخاص بجهاز محلي أو بعيد.للحصول على مثال بعيد انظر مقالة EDN لجون كاستر.
لاحظ أنه سيتعين عليك أيضًا ذلك إنشاء ملف رسالة و سجل مصدر الحدث الخاص بك وإلا فإن جميع رسائل السجل الخاصة بك ستبدأ بشيء مثل هذا:
لا يمكن العثور على وصف معرف الحدث xxx من المصدر xxxx.إما أن المكون الذي يرفع هذا الحدث غير مثبت على جهاز الكمبيوتر المحلي الخاص بك أو التزام التثبيت.يمكنك تثبيت المكون أو إصلاحه على الكمبيوتر المحلي.
إذا نشأ الحدث على جهاز كمبيوتر آخر ، فيجب حفظ معلومات العرض مع الحدث.
تم تضمين المعلومات التالية مع الحدث:
1، لمزيد من المعلومات حول كيفية إنشاء ملف رسالة، راجع البرنامج التعليمي لفين تولدرلوند أو مقالة مايكل هيكس أو يمكنك استخدام MC و تم تضمين ملف RES في مشروع GitHub.
2، قم بتضمين ملف RES في التطبيق الخاص بك عن طريق تضمين messageFile.res في ملف DPR الخاص بك.بدلا من ذلك يمكنك إنشاء ملف dll للرسائل.
program MyTestApp;
uses
Forms,
FormMain in 'FormMain.pas' {MainForm},
EventLog in 'EventLog.pas';
{$R *.res}
{$R MessageFile\MessageFile.res}
begin
Application.Initialize;
3، يتطلب التسجيل لمرة واحدة كتابة حقوق المسؤول إلى السجل، لذلك يتم ذلك عادةً كجزء من عملية تثبيت التطبيق الخاص بك.
//For example
AddEventSourceToRegistry('My Application Name', ParamStr(0));
//or
AddEventSourceToRegistry('My Application Name', 'C:\Program Files\MyApp\Messages.dll');
//--------------------------------------------------
procedure AddEventSourceToRegistry(ASource, AFilename: string);
var
reg: TRegistry;
begin
reg := TRegistry.Create;
try
reg.RootKey := HKEY_LOCAL_MACHINE;
if reg.OpenKey('\SYSTEM\CurrentControlSet\Services\Eventlog\Application\' + ASource, True) then
begin
reg.WriteString('EventMessageFile', AFilename);
reg.WriteInteger('TypesSupported', 7);
reg.CloseKey;
end
else
begin
raise Exception.Create('Error updating the registry. This action requires administrative rights.');
end;
finally
reg.Free;
end;
end;
إذا كنت بحاجة إلى تسجيل أحداث Windows ومتطلبات التسجيل الأخرى، فيمكنك أيضًا استخدام أطر عمل التسجيل مثل log4d و أداة التتبع
يرى هنا إذا كنت تريد الكتابة إلى نافذة سجل الأحداث في Delphi IDE.
لتسجيل الأحداث البسيطة في D5، استخدمت الكود التالي لإضافة رسائل إلى سجل التطبيقات.
- أضف "SvcMgr" إلى جملة الاستخدامات
استخدم هذا الرمز لإضافة رسالتك النصية ورقم المعرف (المعلمة الأخيرة في أسطر LogMessage)
with TEventLogger.create('My Application Name') do begin try LogMessage('Information Message!', EVENTLOG_INFORMATION_TYPE, 0, 1); LogMessage('Error Message!', EVENTLOG_ERROR_TYPE, 0, 2); LogMessage('Warning Message!', EVENTLOG_WARNING_TYPE, 0, 3); LogMessage('Audit Success Message!', EVENTLOG_AUDIT_SUCCESS, 0, 4); LogMessage('Audit Failure Message!', EVENTLOG_AUDIT_FAILURE, 0, 5); finally free; end; end;
أستخدم VCL القياسي لهذا في دلفي 6، لا أستطيع أن أخبرك ما إذا كان هذا متاحًا في دلفي 5 أم لا.جربه بنفسك وأخبرنا إذا كانت هذه الأشياء موجودة في D5.
قم بتعريف متغير عمومي/نموذج من النوع TEventLogger.تم الإعلان عن ذلك في وحدة SvcMgr لذا يجب إضافة هذه الوحدة إلى قائمة الاستخدامات الخاصة بك.إذا كان هذا تطبيقًا عاديًا (أي.ليست خدمة) ثم تأكد من إضافة SvcMgr بعد وحدة النماذج.
سجل الأحداث الخاص بي:TEventLogger;
إنشاء مثيل للمسجل.
MyEventLog := TEventLogger.Create('MyApplication');
للكتابة في سجل الأحداث:
MyEventLog.LogMessage('بدأ MyApplication.'), EVENTLOG_INFORMATION_TYPE);
لا تنسى أن تطلقه في النهاية:
MyEventLog.Free;
هناك أشياء أخرى عليك القيام بها لتسجيل التطبيق في سجل أحداث Windows بحيث تظهر الرسالة دون أن يكون هذا أمامه:
لا يمكن العثور على وصف معرف الحدث (1000) في المصدر (Microsoft Internet Explorer).قد لا يكون لدى الكمبيوتر المحلي معلومات التسجيل الضرورية أو ملفات DLL الخاصة بالرسائل لعرض الرسائل من كمبيوتر بعيد.المعلومات التالية جزء من الحدث: