C# – Windows service Started and stopped automatically, exception handling issue

cnetservicewindows

I have developed a 32 bit service, I am running it in Windows 7 Home Premium x64.
Problem is when I start it, windows gives me the following message

The WLConsumer service on Local Computer started and then stopped. Some services stop
automatically if they are not in use by other services or programs.

I found the following message in the event log

Service cannot be started. System.ArgumentException: Log WLConsumer has already been registered as a source on the local computer.
at System.Diagnostics.EventLogInternal.CreateEventSource(EventSourceCreationData sourceData)
at System.Diagnostics.EventLogInternal.VerifyAndCreateSource(String sourceName, String currentMachineName)
at System.Diagnostics.EventLogInternal.WriteEntry(String message, EventLogEntryType type, Int32 eventID, Int16 category, Byte[] rawData)
at System.Diagnostics.EventLog.WriteEntry(String message, EventLogEntryType type)
at WeblogicConsumerService.WeblogicConsumer.winEventlogMe(String logTxt, String logSrc, Char entryType) in C:\Program Files (x86)\CSI\WeblogicConsumerService\WeblogicConsumer.cs:line 136
at WeblogicConsumerService.WeblogicConsumer.OnStart(String[] args) in C:\Program Files (x86)\CSI\WeblogicConsumerService\WeblogicConsumer.cs:line 63
at System.ServiceProcess.ServiceBase.ServiceQueuedMainCallback(Object state)

This is my codeblock in the OnStart() method

   protected override void OnStart(string[] args)
    {
        #region WEBLOGIC CREDENTIALS
        try
        {
            //Weblogic URL
            this.url = Registry.LocalMachine.OpenSubKey(@"Software\CSI_WL").GetValue("URL").ToString();

            //Queue name
            this.qName = Registry.LocalMachine.OpenSubKey(@"Software\CSI_WL").GetValue("Queue").ToString();

            //Weblogic login name
            this.user = Registry.LocalMachine.OpenSubKey(@"Software\CSI_WL").GetValue("User").ToString();

            //Weblogic password
            this.pwd = Registry.LocalMachine.OpenSubKey(@"Software\CSI_WL").GetValue("Pwd").ToString();

            //Weblogic Connection Factory
            this.cfName = Registry.LocalMachine.OpenSubKey(@"Software\CSI_WL").GetValue("ConnectionFactory").ToString();

            //root folder
            this.rFolder = Registry.LocalMachine.OpenSubKey(@"Software\CSI_WL").GetValue("root").ToString();
        }
        catch (Exception e)
        {
            winEventlogMe(e.Message, "WLRegistryKeys", 'e');
        }
        #endregion

        winEventlogMe("Successful start", "SeriviceStartup", 'i');
        synchro.Enabled = true;
    }

winEventLogMe is the method I am calling for logging.

        public static void winEventlogMe(string logTxt, string logSrc, char entryType)
    {
        #region Log
        //Log to event log

        EventLog theEvent = new EventLog("WLConsumer");
        theEvent.Source = logSrc;
        if (entryType == 'e')
            theEvent.WriteEntry(logTxt, EventLogEntryType.Error);
        else if (entryType == 'i')
            theEvent.WriteEntry(logTxt, EventLogEntryType.Information);
        else if (entryType == 'w')
            theEvent.WriteEntry(logTxt, EventLogEntryType.Warning);
        else
            theEvent.WriteEntry(logTxt, EventLogEntryType.Error);*/
        #endregion
    }

When I comment out the calls to winEventLogMe() method in the OnStart() method, the service starts without an error. So obviously something is wrong with the winEventLogMe() method.
Can someone please help me figure out whats the problem as I am totally clueless on how to solve this issue now.

thanx in advance 🙂


@nick_w I have edited my code as you suggested, the service started succesfully. But on Stopping it I got the following message:

Failed to stop service. System.ArgumentException: The source 'WLConsumer2012' is not registered in log 'ServiceStop'. (It is registered in log 'SeriviceStartup'.) " The Source and Log properties must be matched, or you may set Log to the empty string, and it will automatically be matched to the Source property.
at System.Diagnostics.EventLogInternal.VerifyAndCreateSource(String sourceName, String currentMachineName)
at System.Diagnostics.EventLogInternal.WriteEntry(String message, EventLogEntryType type, Int32 eventID, Int16 category, Byte[] rawData)
at System.Diagnostics.EventLog.WriteEntry(String message, EventLogEntryType type)
at WeblogicConsumerService.WeblogicConsumer.winEventlogMe(String logTxt, String logSrc, Char entryType) in C:\Program Files (x86)\CSI\WeblogicConsumerService\WeblogicConsumer.cs:line 139
at WeblogicConsumerService.WeblogicConsumer.OnStop() in C:\Program Files (x86)\CSI\WeblogicConsumerService\WeblogicConsumer.cs:line 70
at System.ServiceProcess.ServiceBase.DeferredStop()

here is the OnStop() method

        protected override void OnStop()
    {
        winEventlogMe("Successful stop", "ServiceStop", 'i');
    }

These event logs are starting to confuse me a lot. I have done the same method of logging in other services and never encountered such problems. How can I be getting these errors in this service yet its not much different from all the others I have done 🙁

Best Answer

I think this is your problem:

EventLog theEvent = new EventLog("WLConsumer");

Judging by the exception, I am thinking that WLConsumer is the name of the event source. What this means is that you might be better off with this:

EventLog theEvent = new EventLog(logSrc);
theEvent.Source = "WLConsumer";

This is just using the parameters the other way around.

If I do a little decompilation, there is a check like this:

if (!EventLogInternal.SourceExists(logName, machineName, true))

In your case I would think this check is returning true, meaning that it is trying to create a log named WLConsumer but failing because WLConsumer has been registered as an event source.

Edit:

When I have used the event log in the past, I wrote everything to the same combination of source and log. In your case you seem to be using a different combination of source and log each time you write an entry.

From MSDN (emphasis mine):

If you write to an event log, you must specify or create an event Source. You must have administrative rights on the computer to create a new event source. The Source registers your application with the event log as a valid source of entries. You can only use the Source to write to one log at a time. The Source can be any random string, but the name must be distinct from other sources on the computer. It is common for the source to be the name of the application or another identifying string. An attempt to create a duplicated Source value throws an exception. However, a single event log can be associated with multiple sources.

What I would suggest is this:

Use WLConsumer (or WLConsumer2012) as your source, and either

  1. Define your own log, 'WLConsumerServiceEventLog` or something; or
  2. Leave the log blank. They go into the Application log in this case.

Regardless, standard practice seems to be to do something like this prior to running your service for the first time, such as in an installer (copied straight from above link):

// Create the source, if it does not already exist. 
if(!EventLog.SourceExists("MySource"))
{
    //An event log source should not be created and immediately used. 
    //There is a latency time to enable the source, it should be created 
    //prior to executing the application that uses the source. 
    //Execute this sample a second time to use the new source.
    EventLog.CreateEventSource("MySource", "MyNewLog");
    Console.WriteLine("CreatedEventSource");
    Console.WriteLine("Exiting, execute the application a second time to use the source.");
    // The source is created.  Exit the application to allow it to be registered. 
    return;
}

Note the point in the comments re latency. The logs are not necessarily created immediately, so it pays to code with this in mind. You could also use the EventLogInstaller to create the log. This may be the easier option if you are using an installer to deploy your service.

Related Topic