Solved

How do you write to the Event Log

Posted on 2004-08-12
10
466 Views
Last Modified: 2012-06-22
Hi,

I wrote a windows service and I would like it to write to Applications part of the Event Log whenever something
goes wrong or something important happens.

Could someone please explain, step-by-step.  How to do this.  I am really confused.  

I read this in MSDN http://msdn.microsoft.com/library/default.asp?url=/library/en-us/debug/base/using_event_logging.asp
The first two articles here seem to be what I need.  But, I don't know where to put them and how to call them.

For example, I don't know what parameters I would call this with:
BOOL AddEventSource(
   LPTSTR pszLogName, // Application log or a custom log
   LPTSTR pszSrcName, // event source name
   LPTSTR pszMsgDLL,  // path for message DLL
   DWORD  dwNum)      // number of categories
{
If the first parameter, do I just put "Application" ??  For the parth for message DLL, I don't know what to do.  I don't
have a DLL.  Just have a message file with a few messages.  

For this:
void MyReportEvent(
    LPTSTR pszSrcName, // event source name
    DWORD dwEventID,   // event identifier
    WORD wCategory,    // event category
    WORD cInserts,     // count of insert strings
    LPCTSTR *szMsg)    // insert strings
{
I am not really sure what are these strings they are talking about.

Please help.  I really don't know how to do this and detailed step-by-step would be greatly appreciated.

Thanks!
0
Comment
Question by:pavelmed
  • 5
  • 5
10 Comments
 
LVL 86

Expert Comment

by:jkr
ID: 11785369
>>If the first parameter, do I just put "Application" ??

Actually, you could use that, but providing the name of your own application would be more helpful.

But, you don't need to add an event source,all this is overly complicated. You could just use

VOID    AddToMessageLog (   LPTSTR  lpszMsg)
{
    HANDLE  hEventSource;

    TCHAR   szMsg           [   ERROR_BUFSZ];
    LPTSTR  lpszStrings     [   2];


    if  (   !g_bDebug   )
        {
            g_dwErr =   GetLastError();

            // Use event logging to log the error.
            //
            hEventSource    =   RegisterEventSource (   NULL,
                                                        TEXT    (   "MyApplication")
                                                    );

            wsprintf    (   szMsg,
                            TEXT    (   "%s error: %d"),
                            TEXT    (   "MyApplication"),
                            g_dwErr
                        );

            lpszStrings [   0]  =   szMsg;
            lpszStrings [   1]  =   lpszMsg;

            if  (   hEventSource)
                {
                    ReportEvent (   hEventSource,           // handle of event source
                                    EVENTLOG_ERROR_TYPE,    // event type
                                    0,                      // event category
                                    0,                      // event ID
                                    NULL,                   // current user's SID
                                    2,                      // strings in lpszStrings
                                    0,                      // no bytes of raw data
                                    ( const unsigned short**)lpszStrings,            // array of error strings
                                    NULL
                                );

                    DeregisterEventSource   (   hEventSource);
                }
        }
}

and call it like

AddToMessageLog ( "Out of memory");
0
 
LVL 86

Accepted Solution

by:
jkr earned 500 total points
ID: 11785440
Ooops, 'lil correction

VOID    AddToMessageLog (   LPTSTR  lpszMsg)
{
    HANDLE  hEventSource;

    TCHAR   szMsg           [   ERROR_BUFSZ];
    LPTSTR  lpszStrings     [   2];

    DWORD dwErr =   GetLastError();

    // Use event logging to log the error.
    //
    hEventSource    =   RegisterEventSource (   NULL,
                                                TEXT    (   "MyApplication")
                                            );

    wsprintf    (   szMsg,
                    TEXT    (   "%s error: %d"),
                    TEXT    (   "MyApplication"),
                    g_dwErr
                );

    lpszStrings [   0]  =   szMsg;
    lpszStrings [   1]  =   lpszMsg;

    if  (   hEventSource)
        {
            ReportEvent (   hEventSource,           // handle of event source
                            EVENTLOG_ERROR_TYPE,    // event type
                            0,                      // event category
                            0,                      // event ID
                            NULL,                   // current user's SID
                            2,                      // strings in lpszStrings
                            0,                      // no bytes of raw data
                            ( const unsigned short**)lpszStrings,            // array of error strings
                            NULL
                        );

            DeregisterEventSource   (   hEventSource);
        }
}
0
 

Author Comment

by:pavelmed
ID: 11786539
Hi,
Thanks you for your help. I understand this method of resolving the issue, however, would still like to know more about how to implement the same thing through an .mc file, registering and using a message DLL.  Or at least how to remove the default message generated before "THIS IS MY MESSAGE." Also could you please explain the benefits and drawbacks of using the .mc file to hold messages and simply creating a txt file and reading from it.  (This is what I am getting at the moment)

Thanks again
Event Type:      Error
Event Source:      MyApplication
Event Category:      None
Event ID:      0
Date:            8/12/2004
Time:            1:47:30 PM
User:            N/A
Computer:      xxxxxxxxx
Description:
The description for Event ID ( 0 ) in Source ( MyApplication ) cannot be found. The local computer may not have the necessary registry information or message DLL files to display messages from a remote computer. The following information is part of the event: MyApplication error: 997, THIS IS MY MESSAGE.
0
 
LVL 86

Expert Comment

by:jkr
ID: 11786867
>> would still like to know more about how to implement the same thing through an .mc file

See e.g. http://support.microsoft.com/default.aspx?scid=kb;en-us;166902 ("HOWTO: Troubleshooting the "Event Message Not Found" Message"), it explains what registry settings are required. Actually, as a side effect, it also explains your questions about the parameters to 'AddEventSource()' :o)

If you have VC++, you'll find a sample called 'MsgTable' on the CD, which demonstrates how to construct and use a message table resource. Also check out http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndllpro/html/msdn_ntservic.asp ("Creating a Simple Win32 Service in C++"), where my above sample originally came from, it states

Create a text file with the extension .MC containing the descriptions of the messages. I called mine NTServMsg.mc. The format is very specific and is covered in the "Message Compiler" documentation in the Platform SDK.
Run the message compiler (MC.EXE) against your source file, which by default creates an output file called MSG00001.BIN. The compiler also creates a header file (in my case NTServMsg.h) and an .RC file (NTServMsg.rc). You need to repeat this step any time you change the .MC file in your project, so it's handy to add a tool entry in your Visual C++ menu to do this.
Create an .RC file for your project and #include in it the WINDOWS.H file and the .RC file produced by the message compiler.
Include the header file produced by the message compiler in your main project header file so all modules have access to the symbolic message names.
0
 

Author Comment

by:pavelmed
ID: 11796387
jkr,

Thanks for the suggestions and the links.  I read the one called " Creating a Simple Win32 Service in C++" carefully and
did what it said to do.  However, my problem is not resolved.  It still says "The description for Event ID ... cannot be found."  I didn't really understand the HOWTO: Troubleshooting the "Event Message Not Found" Message  article.  What
is this dll it mentions.  What is it for, how do I craete one?  It says "dll or .exe file"  I'm not sure which .exe file they're
refering to (I hope I'm right in assuming that its not theNameOfMyProject.exe).

Please help.  

Thanks.
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 86

Expert Comment

by:jkr
ID: 11796538
>>I'm not sure which .exe file they're refering to (I hope I'm right in assuming that its not theNameOfMyProject.exe).

It is either your executable or a DLL that has the actual message table resource.
0
 

Author Comment

by:pavelmed
ID: 11796774
jkr,

Could you please explain how to make the exe. or DLL file?  Is it by running RC  NTServMsg.rc in the command prompt?
I tried that, but it didn't create an exe or a dll.  

Thanks

0
 
LVL 86

Expert Comment

by:jkr
ID: 11797010
As I wrote above:

From http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndllpro/html/msdn_ntservic.asp ("Creating a Simple Win32 Service in C++"):

Create a text file with the extension .MC containing the descriptions of the messages. I called mine NTServMsg.mc. The format is very specific and is covered in the "Message Compiler" documentation in the Platform SDK.

Run the message compiler (MC.EXE) against your source file, which by default creates an output file called MSG00001.BIN. The compiler also creates a header file (in my case NTServMsg.h) and an .RC file (NTServMsg.rc). You need to repeat this step any time you change the .MC file in your project, so it's handy to add a tool entry in your Visual C++ menu to do this.

Create an .RC file for your project and #include in it the .H file and the .RC file produced by the message compiler.

Include the header file produced by the message compiler in your main project header file so all modules have access to the symbolic message names.
0
 

Author Comment

by:pavelmed
ID: 11822418
jkr,

I got my code working now.
Thank you very much for your help.  I really appreciate it.

0
 

Author Comment

by:pavelmed
ID: 11822436
btw, how do I give these points ?  Are they given automatically when I accept an answer, or do I have to do something else?
0

Featured Post

6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

Join & Write a Comment

Templates For Beginners Or How To Encourage The Compiler To Work For You Introduction This tutorial is targeted at the reader who is, perhaps, familiar with the basics of C++ but would prefer a little slower introduction to the more ad…
Many modern programming languages support the concept of a property -- a class member that combines characteristics of both a data member and a method.  These are sometimes called "smart fields" because you can add logic that is applied automaticall…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.

747 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now