Here are a few tips on passing arguments to a .NET Windows Service.

Install a Windows Service with Arguments

I found the easiest way to install my service with a path that includes arguments, ala:

c:\myservice\myservice.exe --port 8080

was to use sc instead of installutil. For additional reading on both approaches you can check out this Stackoverflow topic.

In order to get your service's install path to include your path you use sc as follows:

sc create MyService binPath= "c:\myservice\myservice.exe --port 8080"

which will set the binary path to include your arguments. Now when you start your service, it will pass those arguments to the main function.

In order to consume these arguments, modify the Main method in your Windows Service project. You should modify Main to parse the args that are passed to it.

Note: You should use something like CommandLineParser to facilitate this. The below example doesn't do this... orperform any argument checking. So do as I say, not as I do.

namespace MyService
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application
        /// that accepts arguments that are supplied by the 
        /// executable path used when the service starts.
        /// </summary>
        static void Main(string[] args)
        {
            // Parse your arguments
            uint port = uint.Parse(args[1]);

            // Start the service with the parsed args
            ServiceBase[] ServicesToRun;        
            ServicesToRun = new ServiceBase[] 
            { 
                // Pass your arguments to your service
                new MyService(port);
            };
            ServiceBase.Run(ServicesToRun);
        }
    }
    
    public partial class MyService : ServiceBase
    {
        public uint Port { get; set; }

        // Accept arguments and do stuff!
        public MyService(uint port)
        {
            InitializeComponent();
            Port = port;
        }
    }
}

Starting a Windows Service with Arguments

Interesting, if you look at the OnStart method in ServiceBase you'll notice it includes arguments. For example...

namespace MyService
{
    public partial class MyService : ServiceBase
    {
        public uint Port { get; set; }

        public MyService(uint port)
        {
            InitializeComponent();
            Port = port;
        }

        // This method gets called with `sc start`
        // and can be used to override arguments during startup
        protected override void OnStart(string[] args)
        {
            // We have start-up args, lets do something with them!
            if(args.Length > 0) {
                Port = uint.Parse(args[1]);
            }

            // DO STUFF
        }

    }
}

As you can see, the OnStart method includes an args array that we can override existing properties in our service with. These arguments get passed if you use sc start as follows:

sc start MyService --port 8080