I’ve been trying to get a Wix installer to work. This particular scenario is pretty simple. I want to configure the database via a custom action, then start a Windows service which then queries the database before starting. This would seem like a commonplace scenario. However, Wix documentations are sparse and I’ve been wrangling with this for some time. I finally found a solution. While I loathe to reference a StackOverflow answer, as a favor to my future self I’m going to do so anyways.
The following defines the component that installs and starts the service and creates a feature that references it.
1 2 3 4 5 6 7 8 9 10 11
The following snippet in Product.wxs actually installs the feature:
1 2 3
This is the initial version of the custom action that I want to run.
The following snippet in Product.wxs runs the custom action. Here it is run after InstallFinalize, the last possible step in the installation’s sequence of events. The condition ensures that it is only run if the product isn’t already installed.
1 2 3
According to the above, the installer tries to start the service before it runs the custom action to configure the database. Of course, since the service requires the database to be set up, it balks.
Among others, I tried running the custom action earlier using the
After="InstallFiles" attributes. The latter makes sense because the installer needs to copy files to the file system before it can execute the script. When inspected with Orca, the MSI has the correct InstallExecuteSequence:
... InstallFiles 4000 DbBatchCmd NOT Installed 4001 InstallServices VersionNT 5800 StartServices VersionNT 5900 ... InstallFinalize 6600
However, the installer never executes the custom action. It always tries to start the service and almost immediately fails. In fact, the custom action only runs when it’s set to
After="InstallFinalize" as above.
One of the key things was provided by the helpful if somewhat verbose Windows installer log, which is created when you start the installer as follows:
msiexec /i myinstaller.msi /l*v myinstaller.log
Someday, Microsoft will have consistent command-line arguments. The log has this to say about the service:
MSI (s) (3C:A8) [17:10:02:607]: Note: 1: 2262 2: Error 3: -2147287038 Info 1721.There is a problem with this Windows Installer package. A program required for this install to complete could not be run. Contact your support personnel or package vendor. Action: DbBatchCmd, location: C:\inetpub\wwwroot\MyApp\Database\, command: C:\Windows\SysWOW64\\cmd /c ""setup_database.cmd" "my_webserver" "my_dbserver"" Action ended 17:10:02: ShipBatchCmd. Return value 1.
This is followed by entries for InstallServices and StartServices. So the installer does try to run the custom action but fails.
The answer is provided by Rob Mensching, who created Wix. According to him,
After="InstallFiles" is correct. However, the execution needs to be “deferred” until the files are actually copied to the file system. Below is the corrected XML.
1 2 3 4 5