2015-05-14 6 views
18

मेरा डेल्फी ऐप आसानी से विंडोज इवेंट लॉग में कैसे लिख सकता है?विंडोज इवेंट लॉग में लिखना डेल्फी

TEventLogger और ReportEvent के बीच क्या अंतर है? मैं ReportEvent फ़ंक्शन का उपयोग कैसे करूं?

+2

इस प्रतीत होता है कि सरल प्रश्न के लिए खोज स्टैक ओवरफ़्लो कई प्रश्नों के बीच फैले उत्तरों को लौटाता है। मैंने एक नया सरल प्रश्न बनाया है और उत्तरों को गठबंधन करने के लिए समय बिताया है और अतिरिक्त जानकारी जो अन्य उत्तरों में नहीं है। मैंने ऐसा इसलिए किया है क्योंकि पहली बार मैं यहां इस उत्तर की तलाश नहीं कर रहा था और सोचा था कि विस्तृत उत्तर और नमूना परियोजना अन्य लोगों की भी मदद कर सकती है। –

+2

आप दूसरे प्रश्न पर ऐसा कर सकते थे। यह भी ठीक है। प्रश्न अब जुड़े हुए हैं। यह सब अच्छा है। http://blog.stackoverflow.com/2010/11/dr-strangedupe-or-how-i-learned-to-stop-worrying-and-love-duplication/ –

+0

आह ठीक, धन्यवाद डेविड, मैं अब बेहतर कैसे समझ में यह काम करता हैं। –

उत्तर

25

आप एक Windows सेवा लेखन और स्थानीय मशीन के विंडोज ईवेंट लॉग करने के लिए लिखने की ज़रूरत रहे हैं तो आप का उल्लेख here रूप TService.LogMessage कॉल कर सकते हैं।

//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 उपयोग कर सकते हैं किसी भी अन्य प्रकार के लिए। TEventLoggerundocumented स्थानीय मशीन के विंडोज इवेंट लॉग को लिखने के लिए टीएस सेवा के लिए सहायक वर्ग here, here और here का उल्लेख किया गया है।

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 एपीआई ReportEvent समारोह के रूप में उल्लेख किया here और here उपयोग कर सकते हैं।

मैंने इसे आसान बनाने के लिए एक साधारण कक्षा बनाई है, यह available on GitHub है।

//----------------- 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. 

ReportEvent के लिए या तो एक स्थानीय या दूरस्थ मशीन के ईवेंट लॉग एक लॉग प्रविष्टि लिख समर्थन करता है। एक दूरस्थ उदाहरण के लिए John Kaster's EDN article देखें।

स्रोत xxxx से घटना आईडी xxx के लिए विवरण नहीं किया जा सकता:


नोट आप भी create a message file और register your event source करने के लिए होता है कि अन्यथा सब अपनी लॉग संदेशों कुछ इस तरह के साथ शुरू हो जाएगा मिल गया। या तो घटक जो इस घटना को उठाता है पर आपके स्थानीय कंप्यूटर पर स्थापित नहीं है या स्थापना दूषित है। आप इंस्टॉल कर सकते हैं या स्थानीय कंप्यूटर पर घटक की मरम्मत कर सकते हैं।

यदि घटना किसी अन्य कंप्यूटर पर उत्पन्न हुई, तो प्रदर्शन जानकारी को ईवेंट से सहेजा जाना था।

निम्न जानकारी घटना के साथ शामिल किया गया था:

1, कैसे एक संदेश फ़ाइल बनाने के लिए अधिक जानकारी के लिए Finn Tolderlund's tutorial या Michael Hex's article देख सकते हैं या आप एक मौजूदा एम सी और RES file included in the GitHub project उपयोग कर सकते हैं।

2, अपनी डीपीआर फ़ाइल में MessageFile.res सहित अपने आवेदन में आरईएस फ़ाइल एम्बेड करें। वैकल्पिक रूप से आप संदेशों के लिए एक डीएलएल बना सकते हैं।

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 के रूप में प्रवेश चौखटे का उपयोग कर सकते अन्य प्रवेश आवश्यकताओं और TraceTool


here देखें कि आप ईवेंट लॉग करने के लिए लिखना चाहते हैं की जरूरत है डेल्फी आईडीई में खिड़की।

+4

ठीक है! बस अपनी लॉग कक्षा में। मैं पुनरावृत्ति रजिस्टर और घटना स्रोत को अपनाने से बचने के लिए कक्षा विधियों के बजाए उदाहरण विधियों के रूप में उनके तरीकों को प्राथमिकता देना पसंद करूंगा। जब घटना का निर्माण किया जाता है और नष्ट होने पर अपमानित होता है तो मैं इवेंट स्रोत पंजीकृत करता हूं। या एक वैश्विक थ्रेडवर बनाएं और इसे एक बार शुरू करें। – TLama

+0

यदि आप इंस्टेंस नष्ट होने पर अपंजीकृत करते हैं, तो क्या ऐसा नहीं होता है कि मौजूदा ईवेंट लॉग प्रविष्टियां अब और नहीं पढ़ी जा सकती हैं? दूसरे शब्दों में, ऑपरेटर के लिए पुरानी घटना लॉग प्रविष्टियों को देखने में सक्षम होने के लिए उदाहरण ज़िंदा होना था? मुझे लगता है कि इवेंट स्रोत को पंजीकृत करना इंस्टॉलेशन का हिस्सा होना चाहिए और निष्पादन योग्य की स्थापना रद्द करने के लिए पंजीकरण करना चाहिए। –

+0

हाय TOndrey, मुझे लगता है TLama मतलब था "RegisterEventSource" API कॉल, नहीं "रजिस्टर रजिस्ट्री में जोड़कर इवेंट स्रोत" :-) –

संबंधित मुद्दे