I created a msi Setup with WiX using WixSharp. It includes several Custom Actions. For instance during installation time I am executing some batch files which are installing and starting a service. And during uninstall it should stop and uninstall the service again.
var dir = new InstallDir(@"%ProgramFiles%\MyCompany\MyProduct",
new Files(@"..\..\..\AllMyFiles\*.*"));
var project = new Project("MyProduct", dir) {
GUID = new Guid("7f22db65-2b23-4df2-b2b2-495f2d369c3d"),
Version = new Version(1, 0, 0, 0),
UI = WUI.WixUI_InstallDir,
Platform = Platform.x64
};
project.Actions = new WixSharp.Action[] {
new ElevatedManagedAction(CustomActions.InstallService,Return.check, When.Before, Step.InstallFinalize, Condition.NOT_Installed),
new ElevatedManagedAction(CustomActions.StartService,Return.check, When.After, Step.PreviousAction, Condition.NOT_Installed),
new ElevatedManagedAction(CustomActions.StopService,Return.check, When.Before, Step.RemoveFiles, Condition.Installed),
new ElevatedManagedAction(CustomActions.UninstallService,Return.check, When.After, Step.PreviousAction, Condition.Installed)
};
Now here comes the crucial part. I need to execute a batch file during install and uninstall which is located somewhere in INSTALLDIR:
[CustomAction]
public static ActionResult StartService(Session session) {
string installDir = session.Property("INSTALLDIR"); //<--this works on install even when using a custom path
string workingDir = Path.Combine(installDir, @"\SomePathToTheBatchFile");
RunCmdMethode(workingDir, "something.bat -some arguments");
return ActionResult.Success;
}
[CustomAction]
public static ActionResult UninstallService(Session session) {
string installDir = session.Property("INSTALLDIR"); //<--this does not give back the right path on uninstall in case the default path was changed during installation
string workingDir = Path.Combine(installDir, @"\SomePathToTheBatchFile");
RunCmdMethode(workingDir, "something.bat -some arguments");
return ActionResult.Success;
}
Everything runs smoothly when using the default path for installation. But if I change the default install path during installation to some custom path the installation step properly finds the .bat and executes it but during uninstall it searches for the .bat file in the default folder. Although the Uninstaller properly removes the files on the correct location. So the custom install path must be saved somewhere. How do I access it properly?
I finally could solve the problem by myself and with some help of Oleg (https://github.com/oleg-shilo/wixsharp/issues/486).
Since session.Property("INSTALLDIR")
should actually work and so I did not make a mistake at that point, I could figure out the root cause, which is setting the IsInstallDir
property to true by using the InstallDir
class instead of the Dir
class. It overwrote the INSTALLDIR
property when uninstalling back to the hard coded default path.
This explains why the setup worked fine as long as using the default path and also why it worked for all the install-custom steps even when using a custom path but not for uninstalling anymore. The reason tho, why I set the IsInstallDir
property to true in the first place is because of some weird behavior when adding all the files to the setup using wildcards. As long as there are multiple files and folders in the source directory it would work just as expected, getting all paths right and so on. But once the source folder only contains a single folder inside which then contains the rest of the setup files within, it sets the inner folder to be the new root folder (kinda strange but once you know about this behavior things start making sense) and so screws up many necessary paths. Using InstallDir
instead of Dir
fixed that.
I might put some work into restructuring the whole thing (if this is even possible in my use case), but for now simply adding a readme file on the same level as the single inner folder solves that problem and that way I could go back using Dir
in the first line:
var dir = new Dir(@"%ProgramFiles%\MyCompany\MyProduct",
new Files(@"..\..\..\AllMyFiles\*.*"));