سؤال

أنا أبحث عن وسيلة (خالية من الألم إلى حد ما) لإضافة بعض دعم سجل أحداث تطبيقات 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.

  1. قم بتعريف متغير عمومي/نموذج من النوع TEventLogger.تم الإعلان عن ذلك في وحدة SvcMgr لذا يجب إضافة هذه الوحدة إلى قائمة الاستخدامات الخاصة بك.إذا كان هذا تطبيقًا عاديًا (أي.ليست خدمة) ثم تأكد من إضافة SvcMgr بعد وحدة النماذج.

    سجل الأحداث الخاص بي:TEventLogger;

  2. إنشاء مثيل للمسجل.

    MyEventLog := TEventLogger.Create('MyApplication');

  3. للكتابة في سجل الأحداث:

    MyEventLog.LogMessage('بدأ MyApplication.'), EVENTLOG_INFORMATION_TYPE);

  4. لا تنسى أن تطلقه في النهاية:

    MyEventLog.Free;

هناك أشياء أخرى عليك القيام بها لتسجيل التطبيق في سجل أحداث Windows بحيث تظهر الرسالة دون أن يكون هذا أمامه:

لا يمكن العثور على وصف معرف الحدث (1000) في المصدر (Microsoft Internet Explorer).قد لا يكون لدى الكمبيوتر المحلي معلومات التسجيل الضرورية أو ملفات DLL الخاصة بالرسائل لعرض الرسائل من كمبيوتر بعيد.المعلومات التالية جزء من الحدث:

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top