none
Report windows service start error in OnStart()

    Question

  • Hello,

     

    I'm writing a windows service which has some work to do with database. I plan to check the database connection in ServiceBase's OnStart() command and when the database is not connectable, make the service not startable or report start fail. How should I report the situation? If code directly returns when connection testing fails, the service still started successfully, and I need to check log file to know the db is dead. Should I use SetServiceStatus() to set service to SERVICE_STOPPED in OnStart()?

    Thursday, May 10, 2007 2:58 AM

Answers

  • I see, by "report" I assumed you mean reporting information to the user.

     

    Normally, if some dependency doesn't exist or can't be locked you can simply set your state to SERVICE_STOPPED via SetServiceStatus.  See http://msdn2.microsoft.com/en-us/library/system.serviceprocess.servicebase(VS.80).aspx for an example OnStart implementation and setting service status.

     

    Using ServiceBase.Stop() actually calls your service's OnStop() method; if your service never really "started" then ServiceBase.Stop() isn't really appropriate.

    Friday, May 11, 2007 1:48 PM
    Moderator

All replies

  • Ideally you'd add event log entries for this.  There are many applications that help administrators manage the health of a computer of set of computers, with one feature being monitoring event log entries.

     

    Alternatively you could write information to a text file; but the event log is the recommended approach.

    Thursday, May 10, 2007 4:03 PM
    Moderator
  •  Peter Ritchie wrote:

    Ideally you'd add event log entries for this.  There are many applications that help administrators manage the health of a computer of set of computers, with one feature being monitoring event log entries.

     

    Alternatively you could write information to a text file; but the event log is the recommended approach.

     

    Hmm, there's a little bit misunderstanding. What I want is: make the service unable to start when some condition is met (i.e. db is dead when trying to start the service.)

    Anyway, I've found that I can use ServiceBase.Stop() to stop service in OnStart() handler.

    Friday, May 11, 2007 7:28 AM
  • I see, by "report" I assumed you mean reporting information to the user.

     

    Normally, if some dependency doesn't exist or can't be locked you can simply set your state to SERVICE_STOPPED via SetServiceStatus.  See http://msdn2.microsoft.com/en-us/library/system.serviceprocess.servicebase(VS.80).aspx for an example OnStart implementation and setting service status.

     

    Using ServiceBase.Stop() actually calls your service's OnStop() method; if your service never really "started" then ServiceBase.Stop() isn't really appropriate.

    Friday, May 11, 2007 1:48 PM
    Moderator
  • I've tried setting service's status to SERVICE_STOPPED when something occurs, but the service's status is still "Running". I still need to stop it manually. And check the task manager, the process still there. My code belows:

     

    Code Snippet

    protected override void OnStart(string[] args)
     {
         IntPtr handle = this.ServiceHandle;
         myServiceStatus.currentState = (int)State.SERVICE_START_PENDING;
         SetServiceStatus(handle, myServiceStatus);

     

        //some logger settings

     

        try
         {

            //test database connection
             Trace("Connection to Database test OK", log4net.Core.Level.Info);
         }
         catch (MySql.Data.MySqlClient.MySqlException me)
         {
             Trace("Database Error!!", log4net.Core.Level.Fatal, me);
             myServiceStatus.currentState = (int)State.SERVICE_STOPPED;
             SetServiceStatus(handle, myServiceStatus);
             return;
         }

        //start servicing threads

    }

     

    Is there some other codes I should add in OnStart()?

    Tuesday, May 15, 2007 6:44 AM
  • When you say you have to manually stop your service, what state is it in when you try to stop it?  Is it "Pending".  If that's the case it sounds like your catch block hasn't been reached yet and the state hasn't yet been set to "stopped".
    Tuesday, May 15, 2007 2:42 PM
    Moderator
  • The status is "Running". And the message logger(Trace()) in the catch block is executed currectly. I can check the log to file to know that db is dead
    Thursday, May 17, 2007 2:18 AM
  •  Peter Ritchie wrote:


    I see, by "report" I assumed you mean reporting information to the user.

    Normally, if some dependency doesn't exist or can't be locked you can simply set your state to SERVICE_STOPPED via SetServiceStatus. See http://msdn2.microsoft.com/en-us/library/system.serviceprocess.servicebase(VS.80).aspx for an example OnStart implementation and setting service status.

    Using ServiceBase.Stop() actually calls your service's OnStop() method; if your service never really "started" then ServiceBase.Stop() isn't really appropriate.


    I also tried the example there, but SCM cannot even start the service, it stops on the call that sets status to SERVICE_START_PENDING.

    Then I tried to just propagate any exception thrown by business code, it seems SCM could catch those exceptions and then stop the service. But I'm not sure if this approach is safe.

    So I wan to ask, is the approach shown in the example the only way to report exceptions in OnStart()? Is my approach acceptable? Thanks.
    Thursday, May 17, 2007 9:20 AM