Introduction
There are a lot of tutorials out there explaining how to create a Windows service using C#. Virtually all of them want you to use a command-line utility called InstallUtil.exe to install the service. But what if you want to install the service on a machine where this tool is not available? And why should I use it in the first place? It is so easy to create a service which can install und uninstall itself using command line arguments or even a GUI. The snippets are available in different places. Let's put them together!
Background
For parsing command line arguments, I use my library CLAReloaded.
The attached code contains a sample service which writes every 30 seconds into a log file. It is a common example. A large portion is created by Visual Studio including the actual installer object. For details, refer to this tutorial.
Using the Code
Having a service (including installer), you first need to set its name, friendly name, and description. They will be later visible in the Services manager. In the attached sample, they are attributes of serviceInstaller
which in turn is a child of SampleServiceInstaller
:
Then, it can be installed/uninstalled by these four lines:
TransactedInstaller installer = new TransactedInstaller();
installer.Context = new InstallContext(null, null);
installer.Context.Parameters["assemblyPath"] = Assembly.GetExecutingAssembly().Location;
installer.Install(new Hashtable());
So why should one use InstallUtil.exe? I really cannot tell...
Points of Interest
This interesting detail here is that the only reference to the service passed to the installer is the location of the service on the hard disk. No need to pass the name or an instance of the service class. This is possible because the program can distinguish if it is called as program or service. This is done by:
if (Environment.UserInteractive) {
} else {
}
You can set some parameters to configure the installation procedure. They are basically identical to the command line arguments which can be passed to InstallUtil.exe. For example, add the following lines, before calling the actuall install/uninstall method:
installer.Context.Parameters["logFile"] = "installer_logfile.log";
installer.Context.Parameters["logToConsole"] = "false";
installer.Context.Parameters["showCallStack"] = "";
For launching a GUI form from a console application, all you need to do is:
Application.EnableVisualStyles();
Application.Run(new SampleForm());
If you encounter an error 5 "Access denied" during starting the service, make sure that the file is readable and executable by user profile SYSTEM
.
If installing/uninstalling fails, make sure you are running WindowsService1.exe with elevated rights.
History
- 2015-11-09: Initial release