.net Installer, custom action, stop and remove windows
I am facing a problem in my .net installer application which will install three windows apps together. In these three applications, one of them is a Windows service. So my installer project has three main exits from these three Windows apps.
During installation, they will all be installed as expected, and after installing Windows Service it will automatically be "START".
However, if I uninstall the application (while the Windows service is in "RUNNING" mode), the installer will show the "use file" dialog and ultimately find that the service will not be removed and the rest will be uninstalled. However, if the Windows service is stopped before uninstallation, it will run well.
I am guessing that the specified problem is due to the installer application trying to uninstall the service.exe file (as it is also included in the installer).
I tried the following alternatives:
-
I tried to overcome this by adding a custom installer where I tried to stop the service. But it doesn't seem to work either. The reason for this is that the default "delete" action will take place before the custom "delete" action. (FAILED)
-
Set the Persistent property of the Primary Output property of the Windows Service application to true. I was under the assumption that the installer would just skip the files associated with the main output. But (FAILED)
Has anyone encountered such a problem ever and please share your thoughts on the same.
How can I stop the service before uninstalling so that the installation does not succeed?
source to share
I had a similar problem with Windows services a long time ago and was able to solve it by calling the method WaitForStatus(ServiceControllerStatus)
. It takes some time for the service to stop, and you continue to work before the service completely stops. Write the logic for deletion and whatever you want to do when the status is Shutdown
stopped.
If you are uninstalling and want to stop the service before uninstalling, then you need to override the remote custom action by adding your code to stop it and then call base.Uninstall
. Keep in mind that for the WaitForStatus
15 second limit, there may not be enough time to shut down the service, depending on how responsive it is and what it does when it shuts down. Also make sure you call Dispose()
in ServiceController
(or Close, as in this example), because if you don't, the internal service descriptor will not be immediately released, and if it is still in use, t will be removed.
This is just an example of how this can be implemented and registered with the EventLogger:
public override void Uninstall(System.Collections.IDictionary savedState)
{
ServiceController controller = new ServiceController("My Service");
try
{
if (controller.Status == ServiceControllerStatus.Running | controller.Status == ServiceControllerStatus.Paused)
{
controller.Stop();
controller.WaitForStatus(ServiceControllerStatus.Stopped, new TimeSpan(0, 0, 0, 30));
controller.Close();
}
}
catch (Exception ex)
{
string source = "My Service Installer";
string log = "Application";
if (!EventLog.SourceExists(source))
{
EventLog.CreateEventSource(source, log);
}
EventLog eLog = new EventLog();
eLog.Source = source;
eLog.WriteEntry(string.Concat(@"The service could not be stopped. Please stop the service manually. Error: ", ex.Message), EventLogEntryType.Error);
}
finally
{
base.Uninstall(savedState);
}
}
source to share