wixsharp
wixsharp copied to clipboard
Version 2.12.0 no longer passes updated deferred properties to the BeforeInstall and AfterInstall hooks.
Im using the Load event to get the OriginalDatabase value and pass is using the deferred property to the other hooks of a ManagedProject. Since version 2.12.0 the default property value is passed, instead of the updated value. 2.10.0 is working as expected.
Code sample:
var project = new ManagedProject(name, new InstallDir($@"%ProgramFiles%\Company\{name}",
new WixSharp.File(exe) ,
new Property("InfoFile", "info.txt") { IsDeferred = true }))
{
...
};
project.Load += args =>
{
var directory = new FileInfo(args.Session.MsiFile()).Directory;
var file = Path.Combine(directory!.ToString(), "info.txt");
args.Session.SetProperty("InfoFile", file);
};
project.BeforeInstall += args =>
{
// this should be {msi-file-directory}/info.txt but is info.txt
var infoFile = new FileInfo(args.Session.Property("InfoFile"));
}
I will heve a look it but it might be related to the way Load event (CA is scheduled). By default, it is now done as soon as UI loaded or MSI executed.
To restore the previous behaviour (scheduling only when UI is finished) you can use this:
project.LoadEventScheduling = LoadEventScheduling.InExecute;
Thank you for the reply Oleg!
Using the LoadEventScheduling.InExecute indeed fixes the issue.
OK, I had a look at it. Indeed, it's all controlled by the time point when Load event is executed. The older version executed it after UI, just when the MSI is loaded for the setup. The latest version allows two additional scheduling mode:
- when MSI is
loaded for displaying UIorloaded for the setup, whichever comes first - on both, when MSI is
loaded for displaying UIandloaded for the setup
Mode 1 is the default, and it is the one that you arguably would be happy with. However, you have discovered a nasty side constraint of MSI, it does not tunnel properties through the session correctly from UI to the install sequence, unless.... wait for it... 🥁 the property name is in capital. MSI treats it the as a public property.
Don't lough, MSI such an archaic technology that it is full of those ridiculous constraints.
Thius you can also fix your original code by simply renaming InfoFile property into INFOFILE.
As a side note, you may want to rewrite your event handler this way:
project.Load += args =>
{
if (args.Session.IsInstalling())
args.Session.SetProperty("INFOFILE", args.Session.MsiFile().PathChangeFileName("info.txt"));
};
OK, I had a look at it. Indeed, it's all controlled by the time point when Load event is executed. The older version executed it after UI, just when the MSI is loaded for the setup. The latest version allows two additional scheduling mode:
- when MSI is
loaded for displaying UIorloaded for the setup, whichever comes first- on both, when MSI is
loaded for displaying UIandloaded for the setupMode 1 is the default, and it is the one that you arguably would be happy with. However, you have discovered a nasty side constraint of MSI, it does not tunnel properties through the session correctly from UI to the install sequence, unless.... wait for it... 🥁 the property name is in capital. MSI treats it the as a public property.
Don't lough, MSI such an archaic technology that it is full of those ridiculous constraints. Thius you can also fix your original code by simply renaming
InfoFileproperty intoINFOFILE.As a side note, you may want to rewrite your event handler this way:
project.Load += args => { if (args.Session.IsInstalling()) args.Session.SetProperty("INFOFILE", args.Session.MsiFile().PathChangeFileName("info.txt")); };
Never would have guessed the property-name matters.
Thank you for the detailed explanation!
Just a small readability addition, INFO_FILE also seems to work :)