I’ve got a project at work that needs an MSI. I really didn’t want to use InstallShield, so I looked into WiX. WiX probably deserves its own thread, but I’ll just say that I’m a big fan.
The requirements for this installation, at first, seemed pretty straight forward. The installation does not have any UI or dialogs; meaning the user cannot choose any installation options or the destination path. For our purposes, that’s fine.
But here’s where it gets a bit difficult. We have to lay down Tomcat with a web service. That means that the project is dependent on the JRE. After some investigation, it appears that Sun doesn’t offer a jre bootstrapper. They only offer the jre installer itself, which is an msi wrapped in an executable. Anybody familiar with MSI knows that an MSI package cannot install another MSI package. This fact means that to install the JRE, we would have to either use a tool that included a jre bootstrapper or develop the bootstrapper ourselves.
We decided on a third option: include the contents of the jre and deploy it as a private jre. That means that the entire jre would be deployed to a subdirectory of the destination folder, and Tomcat would be configured to use this private jre. Fortunately, this use of the jre appears to not violate any redistribution agreements. This approach also means that our jre will not impact the target system, meaning no conflicts with existing jres. It also simplifies the installation scenario in that we don’t have to check for an existing jre – hence, no need for a bootstrapper, and we can continue to use WiX.
Now on to Tomcat. Tomcat can be run from the command line, or installed as a windows service. In our case, it must be installed as a windows service. To install Tomcat as a windows service, one must execute the service.bat file(located in tomcat’s bin folder) with the “install” argument.
After we’ve deployed tomcat and installed it as a service, we must deploy our web service package(packed as a WAR file). Tomcat, if it’s running(or when it’s run again) will pick up the war file and unpackage and deploy it automatically.
So far, this isn’t very complicated. At least I didn’t think so until I had to actually implement these requirements. The “install as a windows service” requirement presents some headaches. I mentioned that one must execute the service.bat file to install Tomcat as a service. We have to do this from the installer. After the batch file has been executed, we must then run NET START to start the service. That means that our installer has two custom actions: one to run the batch file, and another to start the service. Upon removal, the installer stops the service and uninstalls the service.
All of this behavior is implemented, and it runs… intermittently. On some machines, we get an MSI error stating that the product could not be installed. I’ve concluded that for some reason the batch file is not being executed. So for more information, I ran the MSI with verbose logging. Lo and behold, the batch file was executed.
It’s somewhat consistent. On the test machines where this is an issue, it’s consistent. But it doesn’t behave like this on all environments. On the machines where the batch file isn’t being executed, if we run the msi with verbose logging the batch file is always executed, and everything is installed correctly.
This is very frustrating. We can’t expect the customer to execute the msi package with verbose logging. Unfortunately, I’m not dedicated to this project, so I only get to work on it for a few hours every couple of weeks. At this point, I have no idea as to the root cause, and if it can be corrected.
Is there a reason the ServiceInstall and ServiceControl elements can’t be used to install then start/stop the service? It depends greatly on what the batch file does, but I’m pretty certain you will find everything is much more stable using the built-in actions of the Windows Installer than shelling out to batch files.
Comment by Rob Mensching — March 11, 2007 @ 10:40 am
I would love to use the out of the box actions. However, I’m afraid they cannot be used in this scenario. Scratch that – I’m unaware of how to utilize them in this specific case, and to get them to work.
The service.bat file sets up a bunch of temporary environment variables. It then calls tomcat5.exe a few times. I’m not a tomcat guy, but from what I can gather from the batch file, the first execution installs the service. The second time the executable is invoked, it apparently sets some jvm runtime options. The third time it’s invoked, it sets still more jvm options.
And this tomcat5.exe is the actual executable for the windows service.
My point is, that I know of no other way to advertise tomcat as a Windows Service. So I’m not sure the ServiceInstall action can be applied here.
Then there’s the issue of ServiceControl. I tried using it early on for this project, but couldn’t get it to work, so I gave up after a few hours. I think I’ll try it out again.
Comment by treyhutcheson — March 13, 2007 @ 10:16 am
I’m just learning to use Wix and need to do exactly what you did : deploy a private jre in my installer. Could you help me out and give me more details of how you did it? Other than the files, are there any tricks I need to know? Are there any registry modifications? Thanks.
Comment by BMD — August 30, 2007 @ 2:44 pm
Hello
Is there any method or procedure to install dotnet framework using wix (not using bootstrapper)?
Comment by ravishankar — November 7, 2009 @ 7:56 am