wix pass option to msi for repair - wix

When I repair using the msi, a registry entry is properly re-created. When using the exe generated by Burn, the entry is not-recreated, unless the exe associated with the reg entry also requires compare.
I wonder if, when burn invokes msi, if it is overriding the default /fm behavior of msiexec.
That switch means "repair all required computer-specific registry entries "
Is there any way I can confirm, deny, or modify that behavior?

When planning a "Repair" operation in Burn the REINSTALLMODE is "cmuse". For a "Modify" operation the REINSTALLMODE is "cmuso". So "m" is present in both cases.
The Burn log file should say, "Planning action: Action" and that will tell you which it is doing. If you are executing a Repair operation and there is not newer version of the executable on the machine than what your MSI expects, Burn's REINSTALLMODE should work. If you are doing a "Repair", look in the generated MSI log file for the same Burn execution and see what the Component states are for the Components that are not repaired. That should help you track back to see why the Component was not fixed.
From the provided log file:
Command Line: ARPSYSTEMCOMPONENT=1 MSIFASTINSTALL=7 REINSTALLMODE=cmuse
REBOOT=ReallySuppress IGNOREDEPENDENCIES=ALL CURRENTDIRECTORY=C:\temp
CLIENTUILEVEL=3 MSICLIENTUSESEXTERNALUI=1
The lack of REINSTALL=ALL shows that EnableFeatureSelection='yes'. Either remove that attribute (or change it to the default 'no') or your BA needs to handle the OnPlanMsiFeature() callback

Related

Wix msi updated property value not working during installation

Working with Wix in Visual Studio. I have a public property defined in Product node of wxs file.
<Property Id="MYPROP" Value="123456789"/>
The property value is passed as commandline argument to a deferred custom action executable. I'm able to receive it in the exe as well. The problem is even if I update the Property using vbs (verified through vbs select as well), when I launch the msi, it still passes the default/original value (123456789) to the custom action executable.
Also tried msiexec.exe /i myinstaller.msi MYPROP=SomeOtherValue
I'm still seeing the original value. What's wrong?
Maybe try this simple thing first:
<Property Id="MYPROP" Secure="yes" Value="123456789"/>
Essentially you need to add a property to the SecureCustomProperties list to have them pass properly to deferred mode in secure desktop environments.
See more information on SecureCustomProperties here. The technical details here are a little bit in flux because of Windows changes, so please just try this first - there could be several other reasons.
How do you use this property? What does it do?
When an msi is run, windows caches the msi file in %windows%\Installer folder. When that msi is run again, windows checks if an msi with identical PackageCode exists in the cache, if so then it uses the cached msi file instead.
PackageCode: identifies each unqiue msi installer package - even if it only has different properties.
In short, when a property is updated using a vbscript etc, then the PackageCode has to be updated as well. This will ensure that after updating msi, the same msi can be used on the same system and windows will not use the cached msi.

Why does MSI installer succeed when chosen component was not installed?

I have an MSI installer package that enforces the user to choose from a list of possible components to install, like "Version 2018" / "Version 2019" / "Version 2020". The chosen components will install themselves in a folder inside "ProgramData" that is usually writeable by every Administrator account on the system. However, in a recent customer support, this folder was created by the SYSTEM account. Probably the customer's IT installed the environment with SYSTEM privileges.
When the installer tries to put files into this folder it obviously fails. The problem is that the installer notices the missing permission, but still succeeds.
Is there any way to enforce MSI installer to abort / throw an error when a user-chosen component (or any other essential component) could not be installed?
What you want should be the default behavior of WiX / MSI as noted below. It's hard to say what's going on without a logfile.
Take a look at the WiX File#Vital attribute: https://wixtoolset.org/documentation/manual/v3/xsd/wix/file.html
If a file is vital, then installation cannot proceed unless the file
is successfully installed. The user will have no option to ignore an
error installing this file. If an error occurs, they can merely retry
to install the file or abort the installation. The default is "yes,"
unless the -sfdvital switch (candle.exe) or SuppressFileDefaultVital
property (.wixproj) is used.
It sets the underlying msidbFileAttributesVital bitmask in the Windows Installer File table as documented at:
https://learn.microsoft.com/en-us/windows/win32/msi/file-table
The file is vital for the accurate operation of the component to which
it belongs. If the installation of a file with the
msidbFileAttributesVital attribute fails, the installation stops and
is rolled back. In this case, the Installer displays a dialog box
without an Ignore button. If this attribute is not set, and the
installation of the file fails, the Installer displays a dialog box
with an Ignore button. In this case, the user can choose to ignore the
failure to install the file and continue.

Self-deleting installer in WiX

I would like my MSI to self-delete after the installation process is complete. How can I achieve this? Anyway to do it in WIX only? Do you have to create a custom action?
For those wondering, this installer is generated on the fly and bundled to a specific configuration. After the installation is complete, the MSI file has no use anymore (the user must download a new installer with a fresh configuration to reinstall).
This isn't going to be useful, mainly because the MSI file is needed after the install is complete. Rule 31:
http://blogs.msdn.com/b/windows_installer_team/archive/2006/05/24/605835.aspx
Any kind of repair (automatic or user repair) will require the original MSI file. You're better off deleting it at uninstall time.
In general, the way I've done this type of thing is to get an executable into the user's temp location (don't install it there, copy it there with a custom action) and arrange for it to run and delete the MSI file. Just rely on eventual cleanup of the temp directory to delete the exe. However, it won't be transparent if it requires elevation to do the delete, and popups of unfamiliar programs asking for elevation may get denied.

Schedule a Reboot if there is a change in file version

I have a MSI package, which installs a Driver, however the Uninstall of the driver require a Reboot. for which I had scheduled a Standard Custom Actions (scheduleReboot) after InstallFinilize, which works fine.
Now I would like to Schedule reboot only if I am replacing the "driver" file. is there any way of determining "Installed file version" and the "to be installed file version" and based on compassion, if there is a change, schedule reboot.
In some cases the Windows Installer can determine whether a system restart is necessary. For example, the ScheduleReboot action can be used to force the installer to prompt for a restart after installing drivers that require a restart. If the installer attempts to replace files that are in use, it automatically prompts the user to restart even if ScheduleReboot has not been used. The ForceReboot action must always be used with a conditional statement such that the installer triggers a restart only when necessary. For example, a restart may only be required if a particular file is replaced or a particular component is installed.
Each product installation is unique and a custom action may be required to determine whether a restart is needed. There are tables in the Windows installer database which you and use for Searching for Existing Applications, Files, Registry Entries or .ini File Entries and to set a property.
Note: When Replacing Existing Files, Windows Installer determines whether the component's key file is already installed before attempting to install the files of any component. If the installer finds a file with the same name as the component's key file installed in the target location, it compares the version, date, and language of the two key files and uses file versioning rules to determine whether to install the component provided by the package. If the installer determines it needs to replace the component base upon the key file, then it uses the file versioning rules on each installed file to determine whether to replace the file.

How can I execute a Custom Action as System user with Wix 3.0, before checking to see if files are in use?

So I have a Wix 3.0 project that installs an IIS7 Native Code Module. When uninstalling I would like to be able to shut down the IIS7 application pools before deleting the file so that a reboot is not necessary.
I am using the appcmd utility to shut down the app pools in a CustomAction element, but when I attempt to do an uninstall I get this error before the customaction is ever invoked:
The setup must update files or
services that cannot be updated while
the system is running. If you choose
to continue, a reboot will be required
to complete the setup.
I have the "After='InstallInitialize'" property set on the CustomAction, because the documentation says that any deferred/not-impersonated custom action must come between InstallInitialize and InstallFinalize.
So is there some way to have a custom action execute before this check for files in use is made? Or disable this check for a given file, or make the check happen later in the sequence?
Yes, you can specify the order for actions to occur by modifying the Sequence column in the InstallExecuteSequence table within the MSI file.
Get the ORCA tool to examine the MSI file to see what I mean, and use a Javascript script to modify the MSI as appropriate.