I have a standard .NET windows service written in C#.
Can it install itself without using InstallUtil? Should I use the service installer class? How should I use it?
I want to be able to call the following:
MyService.exe -install
And it will have the same effect as calling:
InstallUtil MyService.exe
Yes, that is fully possible (i.e. I do exactly this); you just need to reference the right dll (System.ServiceProcess.dll) and add an installer class...
Here's an example:
Here is a class I use when writing services. I usually have an interactive screen that comes up when the service is not called. From there I use the class as needed. It allows for multiple named instances on the same machine -hence the InstanceID field
Sample Call
The class itself
Process QProc = new Process();
QProc.StartInfo.FileName = "cmd";
QProc.StartInfo.Arguments ="/c InstallUtil "+ "\""+ filefullPath +"\"";
QProc.StartInfo.WorkingDirectory = Environment.GetEnvironmentVariable("windir") + @"\Microsoft.NET\Framework\v2.0.50727\";
The above examples didn't really work for me, and the link to the forum as a #1 solution is aweful to dig through. Here is a class I wrote (in part), and the other bit is merged from this link I found buried somewhere
To install a service, run the InstallAndStart command as follows:
Make sure the account that is running the program has permission to install services. You can always 'Run As Administrator' on the program.
I have also included several commands for non-api access which do not install or remove services, but you can list them and control several (start, stop, restart). You really only need to elevate permissions for installing or removing services.
There are a couple of commands for getting and setting environment variables as well, such as
OPENSSL_CONF
orTEMP
. For the most part, the parameters and method names should be pretty self-explanatory.In the case of trying to install a command line application as a Windows service try the 'NSSM' utility. Related ServerFault details found here.
You can always fall back to the good old WinAPI calls, although the amount of work involved is non-trivial. There is no requirement that .NET services be installed via a .NET-aware mechanism.
To install:
OpenSCManager
.CreateService
to register the service.ChangeServiceConfig2
to set a description.CloseServiceHandle
.To uninstall:
OpenSCManager
.OpenService
.DeleteService
on the handle returned byOpenService
.CloseServiceHandle
.The main reason I prefer this over using the
ServiceInstaller
/ServiceProcessInstaller
is that you can register the service with your own custom command line arguments. For example, you might register it as"MyApp.exe -service"
, then if the user runs your app without any arguments you could offer them a UI to install/remove the service.Running Reflector on
ServiceInstaller
can fill in the details missing from this brief explanation.P.S. Clearly this won't have "the same effect as calling: InstallUtil MyService.exe" - in particular, you won't be able to uninstall using InstallUtil. But it seems that perhaps this wasn't an actual stringent requirement for you.