I'm working on an installer that copies files into Program Files and then runs a service (via one of the files that was copied over). On the first installation this will work with no problems, but issues start to occur when the installer is run and the service is already running on the machine. This is because the installer is attempting to replace the files that already exist in Program Files, but one of those files is in use by the Windows service, so it cannot be replaced unless the service is stopped.
So I decided to use the ServiceController API to stop the service when installation begins, install the files (overwriting the existing files), and start to service again. There is very little to the code, but here it is:
Instantiate ServiceController:
try
{
service = new ServiceController(serviceName);
}
catch (InvalidOperationException ioe)
{
// ...
}
Stopping the service:
if (service.Status != ServiceControllerStatus.Stopped)
{
service.Stop();
}
Then wait for the service to be stopped and install the files:
service.WaitForStatus(ServiceControllerStatus.Stopped);
// install files...
And lastly restart the service:
service.Start();
With this code, the service.WaitForStatus()
method will just wait forever (or longer than I'm prepared to wait at least- up to an hour). The strange thing is that I can run this code, write service.Status()
to a log, check the service manually to see that it has stopped, check the log and see that ServiceController thinks the service is still running.
At first I thought that the issue was with service.Stop()
so I tried creating a couple of Process
objects that got the service PID and then killed the task, which stops the service instantly, but still ServiceController
will not recognise that the service has stopped. If I remove the service.WaitForStatus()
method from my code, an exception will be thrown since the installer is trying to overwrite a file that is in use by the service.
Also, I've tried this with different services, but the result is always the same, leading me to believe that the issue is not with the service itself.
Why is ServiceController
not recognising that the service has stopped? Is there a solution or workaround to this problem? I'm working with .NET 2.0, so anything that requires higher is, unfortunately, not an option for me. Cheers.