Thursday, May 14, 2009

C# Service to start and stop a process at system boot

As anyone who's used Linux before knows, there's an incredibly easy way to start a server program up (even if it's not coded as a daemon) during system startup, just drop a line in /etc/rc.d/rc.local that starts the process nohup and throw an ampersand on the end of the command line (optionally redirect stdout/stderr) and you're good to go.

Windows systems don't have this. Sure there is the Autexec.nt file but this is sure to get deprecated in future releases of the OS... plus the fact that it runs before the major subsystems are initialized. What does that leave for Windows systems? You could put the program you want to start in a user's "Startup" folder but that requires a user to login, and would get killed when that user logged out. No good for a server application. In Microsoft's infinite wisdom, the only reliable way of doing this is to write a Windows service to start the program up and shut it down.

At work, one of my coworkers needed to do something like this, he had written a Progress program that just reads a DB table every so often and performs an action as needed, and he had a .BAT file to start the program up to test /run it, but no way of making the program run automatically when the server started up. I assisted him with this today. Due to copyright I can't include all the code, but the steps are simple.

  1. Startup a new Windows Service project in Visual Studio (we use 2008).
  2. In the service1.cs file in the "public partial class" section that is generated for you, define a class level variable:

    protected System.Diagnostics.Process m_process;
  3. In the OnStart() method, start up the program you want to startup along with any parameters. Note that you'll probably want to do what we did and read all of this in from a configuration file. In the long run this is what you'll have:

    string strProgram, strParameters;
    ...
    // Set strProgram & strParameters accordingly...
    ...
    m_process = System.Diagnostics.Process.Start(strProgram, strParameters);
  4. You should probably add exception handling and logging if you've got time. We needed something quick & dirty. Basically, if the process fails to start, your service won't start up anyhow... we thought that was just fine for our needs.
  5. In the OnStop() method, you need to gracefully shut down whatever process you started up. In this case, there was no graceful shutdown method (CTRL-C), so we just did:

    m_process.Kill();
  6. You'll then need to build an Install / Setup application to install your service.
It's a huge pain in the ass for something you can do in 30 seconds in Linux, but it's the "right" way for Windows...

1 comment:

  1. I am extremely impressed by your subject matter expertise, John.

    I would really like to hear more about your game development too!

    I am setting up a site for new writers and those that want to support them. I am in the finishing stages of publishing my first book - a fantasy fiction novel.

    Who knows ... maybe someday you can develop a game based on that storyline ...

    You can find my blogger page at tod-langley.blogspot.com

    Good luck.

    ReplyDelete