Synchronizing Windows Installer Custom Events
I was working on an installer today at
work. Its an installer for a windows service, so after I copied
some files I wanted to run a batch file that would register the
service. So the install was working fine, I added the batch file
as a custom action on the install event, I would copy the necessary
files, run the batch file, and I could fire the service up. Now,
I also wanted to be able to use the msi file to uninstall the service
as well. So I needed to run another batch file that would
uninstall the windows service before the files were removed. No
problem, I thought, I can just add another custom action to the
uninstall event that would run the appropriate batch file. So I
set it up, installed the service and immediately tried to uninstall
it. I saw the dos prompt come up, but I got a
FileNotFoundException when I tried to uninstall the service.
It seems the .exe was already gone by the time I tried to uninstall it.
I was perplexed, why would they schedule my custom action to run AFTER
the installer had already removed the files? So I messed around
with it a litle more, but I couldn’t figure it out. Then a
thought came to me, here was the code I was using to execute the batch
file for the install and uninstall:
System.Diagnostics.Process.Start(batchFilePath);
What this does is start a new process using the
path provided. After the new process starts, the code continues
on executing without waiting for the new process to complete.
This is fine for the install because by the time I’m running my batch
file theres nothing left for the installer to do, however, for the
uninstall the installer was starting my batch file, and then continuing
the uninstall process and there was a race condition between my batch
file and the uninstaller to get to the .exe first. So I needed to
modify my code slightly to make the uninstall work properly, I needed
to make the uninstaller wait for my batch file to finish its task.
using System.Diagnostics;
Process p = Process.Start(batchFilePath);
p.WaitForExit();
This code will make the current process wait
until the process p has exited, thus allowing my batch file to
uninstall the windows service before it removed the .exe from my disk.
Just a little tip for those of you running into a similar problem, it was bugging me for about an hour this evening [:)]
rlewallen said,
Wrote on June 23, 2005 @ 5:41 am
I remember not being able to get my code to work that way. I had to do something like this:
while (!(processStopIIS.HasExited))
{
System.Threading.Thread.Sleep(1000);
}
Anonymous said,
Wrote on June 23, 2005 @ 10:47 am
Your tip applies to installers in general… but in your specific example, why didn’t you use a ServiceInstaller and ServiceProcessInstaller? What does your batch file do?
breichelt said,
Wrote on June 23, 2005 @ 7:16 pm
The batch file was used to register the service by using the installutil.exe program. The service used to be installed by copying the exe and then running the batch file, this is just a first step towards making an install with some custom parameters.