Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

How do you write to the Event Log

Posted on 2004-08-12
10
Medium Priority
?
546 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 2000 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
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

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

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

What is C++ STL?: STL stands for Standard Template Library and is a part of standard C++ libraries. It contains many useful data structures (containers) and algorithms, which can spare you a lot of the time. Today we will look at the STL Vector. …
Article by: evilrix
Looking for a way to avoid searching through large data sets for data that doesn't exist? A Bloom Filter might be what you need. This data structure is a probabilistic filter that allows you to avoid unnecessary searches when you know the data defin…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.
Suggested Courses

971 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