Unable to prompt for reboot after installation with Wix Bootstrapper project - wix

I have a Wix Project and also a Bootstrapper. I want to prompt the user to restart after the last MSI is run.
Here is the Bootstrapper-
<Chain>
<MsiPackage SourceFile=".\Some.msi" Compressed="yes" />
<MsiPackage Id="MyMsi"
Compressed="yes"
Cache="no"
DisplayInternalUI="yes"
SourceFile="$(var.MyInstaller.TargetPath)"
Visible="no"/>
</Chain>
In my MSI, I have -
<Property Id="REBOOT" Value="Force"/>
and
<InstallExecuteSequence>
<ScheduleReboot After='InstallFinalize'>NOT REMOVE</ScheduleReboot>
</InstallExecuteSequence>
But the prompt doesn't show up. In the log I can find these lines-
Property(S): MsiRebootActionScheduled = 1
MSI (s) (40:64) [23:52:23:990]: Value of RebootAction property is 1
MSI (s) (40:64) [23:52:23:990]: Windows Installer requires a system restart. Product Name: XXX x64 Installer v3.0.0.0. Product Version: 3.0.0.0. Product Language: 1033. Manufacturer: XXX. Type of System Restart: 2. Reason for Restart: 2.
MSI (s) (40:64) [23:52:23:990]: Product: XXX x64 Installer v3.0.0.0. Restart required. The installation or update for the product required a restart for all changes to take effect. The restart was deferred to a later time.
Any suggestion on how to make this work?

I would remove the reboot code from your MSIs and just add the one into the bootstrapper. Adding reboot into bootstrapper was answered on this previous question.

Related

(Wix) MSI uninstall is very slow. Log shows slowness is when shortcuts are being removed

Found a similar question, but the the accepted "answer" is not actually an answer at all: MSIEXEC: "Executing op: ShortcutRemove" step is very slow
Is there a know issue with Wix / Windows Installer being very slow when uninstalling shortcuts?
I have a msi project that creates a lot (85+) of shortcuts in my installation folder. When I install, all goes very quickly and completes successfully in under a minute. However, when I uninstall, it takes in excess of 6-8 minutes. Computer is physical machine with a fast SSD. tested on Windows 10 Pro and Windows Server 2019.
All shortcuts are created on the local C: drive and target files on that same drive.
I am not very experienced with Wix and the Windows Installer, but the uninstall log looks clean to me. Only the ShortcutRemove operations taking longer then expected and every one has "Note: 1: 2318 2: C:\Config.Msi\??????.rbf" (File does not exist). Each ShortcutRemove operation takes 4 to 5 seconds, which obviously adds up because of the (admittedly high) number of shortcuts that I need to create.
From the log, there is about 3 seconds delay between every line showing error "Note: 1: 2318" and the following "Executing op: SetTargetFolder" line.
The project has had this many shortcuts for many years, but I only started noticing the slow down for uninstalls in mid 2019.
Build Environment / Tools
Visual Studio Pro 2017
Wix version 3.11.2.4516
Windows Installer. V 5.0.19041.1
UPDATE 1 - 28-Aug-2020
I suspect that this may be an issue with a Windows o/s patch or new security policy, because I have been using the same .msi and Wix project for a few years and did not see the slow down on Windows 10 prior to mid 2019 - the related post I referenced at the top is from that period as well. I also suspect that this may be happening to many other .msi projects, but the developers are not noticing because they only have a very small (normal) number of shortcuts.
Additionally, I just tested on Windows Server 2016 and found that uninstall is NOT slow on that o/s at all!
FAST: Microsoft Windows Server 2016 Datacenter, Version 1607 (OS Build 14393.3564)
Slow: Microsoft Windows Server 2019 Datacenter, Version 1809 (OS Build 17763.1397)
Slow: Microsoft Windows 10 Pro, Version 2004 (OS Build 19041.450)
This is an extract of the uninstall log:
MSI (s) (98:54) [13:09:59:071]: Using source file security for destination.
MSI (s) (98:54) [13:09:59:073]: Note: 1: 2318 2: C:\Config.Msi\13a736b0.rbf
MSI (s) (98:54) [13:10:01:503]: Executing op: SetTargetFolder(Folder=23\My Tiny Utilities\)
MSI (s) (98:54) [13:10:01:508]: SHELL32::SHGetFolderPath returned: C:\ProgramData\Microsoft\Windows\Start Menu\Programs
MSI (s) (98:54) [13:10:01:509]: Executing op: ShortcutRemove(Name=lddyopzj|Touch)
MSI (s) (98:54) [13:10:01:513]: Verifying accessibility of file: Touch.lnk
MSI (s) (98:54) [13:10:01:515]: Using source file security for destination.
MSI (s) (98:54) [13:10:01:516]: Note: 1: 2318 2: C:\Config.Msi\13a736b1.rbf
MSI (s) (98:54) [13:10:03:964]: Executing op: SetTargetFolder(Folder=C:\MyTinyUtilities\Shortcuts\)
MSI (s) (98:54) [13:10:03:966]: Executing op: ShortcutRemove(Name=n5w0rmgl|Touch)
MSI (s) (98:54) [13:10:03:970]: Verifying accessibility of file: Touch.lnk
MSI (s) (98:54) [13:10:03:974]: Using source file security for destination.
MSI (s) (98:54) [13:10:03:977]: Note: 1: 2318 2: C:\Config.Msi\13a736b2.rbf
This is an extract of my shortcut creation script/code:
<!--Start Menu Shortcuts-->
<Fragment>
<DirectoryRef Id="DirShortcutsStartMenu">
<Component Win64="no" Id="CMP_Shortcuts_StartMenu" Guid="86F485AE-B257-4E8A-8D06-59EE9161B8F9">
<RegistryValue Root="HKCU" Key="Software\MyTinyUtil" Name="Start Menu Created" Type="string" Value="Yes" KeyPath="yes" />
<Shortcut Id="SM_Touch" Name="Touch" Description="Update file modified date" Target="[MTUINSTALLROOT]Touch.exe" />
...
I create about 10 shortcuts on the Start menu path
...
<RemoveFolder Id="Remove01" On="uninstall" />
</Component>
</DirectoryRef>
</Fragment>
<!-- Shortcut in installation Folder-->
<Fragment>
<DirectoryRef Id="DirShortcutsInstallFolder">
<Component Win64="no" Id="CMP_Shortcuts_InstallFolder" Guid="102EC0F4-03BD-48E9-8086-6D5DA4624FA3">
<RegistryValue Root="HKCU" Key="Software\MyTinyUtil" Name="Duplicate Shortcuts" Type="string" Value="yes" KeyPath="yes" />
<Shortcut Id="IF_Touch" Name="Touch" Description="Update file modified date" Target="[MTUINSTALLROOT]Touch.exe" Directory="Dir_C_Shortcuts_File_Utils" />
...
I create in excess of 85 shortcuts in a sub-folder of my installation folder.
...
<RemoveFolder Id="Remove02" On="uninstall" />
</Component>
</DirectoryRef>
</Fragment>
I also experienced the same issue. And solved.
Try to have no more than 5 pinned items on taskbar.
I think the uninstallation will complete faster if you reduce the number of pins.

Wix Installer error during upgrade-The setup must update files or services that cannot be updated while system is running

I come upon the warning message during uninstalls a product or major updates in the uninstall phase (when a product service is running):
"The setup must update files or service that cannot be updated while the system is running. If you choose continue, a reboot will be required to complete the setup."
Story starts here
I have developed the windows service and created the installer [msi] using Wix, then distributed to users. it is working as expected.
Now, it's time to deliver a new build with service enhancements. Hence, I have created a new msi. I was hoping that the execution of new msi shall upgrade the existing application.
But I get below error
The setup must update files or services that cannot be updated while the system is running
To support MSI upgrade, I have made below changes
Existing code for Product section
<?define UpgradeCode = "{3D197FE4-86DF-31FD-A0CD-21B5D3B97ABC}" ?>
<Product Id="$(var.ProductCode)"
Name="!(loc.ProductName_$(var.Platform)) $(var.ProductVersion)"
Language="!(loc.Language)"
Version="$(var.BuildVersion)"
Manufacturer="!(loc.Company)"
UpgradeCode="$(var.UpgradeCode)">
Changed code, Here Product ID changed to *
<?define UpgradeCode = "{3D197FE4-86DF-31FD-A0CD-21B5D3B97ABC}" ?>
<Product Id="*"
Name="!(loc.ProductName_$(var.Platform)) $(var.ProductVersion)"
Language="!(loc.Language)"
Version="$(var.ProductVersion)"
Manufacturer="!(loc.Company)"
UpgradeCode="$(var.UpgradeCode)">
Observe that upgrade code is not changed from old version to new version.
Existing code for upgrade
<MajorUpgrade DowngradeErrorMessage="!(loc.DowngradeErrorMessage)" />
Updated code for upgrade
<MajorUpgrade DowngradeErrorMessage="!(loc.DowngradeErrorMessage)"
AllowDowngrades="no"
AllowSameVersionUpgrades="yes"
RemoveFeatures="ALL"
Schedule="afterInstallInitialize"/>
Is it anything to do with service?
<ServiceControl Id="myservice"
Name="GatewayService"
Start="install"
Stop="both"
Remove="uninstall" Wait="yes" />
Install Sequence
How to get rid of this prompt? Also why it's coming if service is stopped.
Some part of logs
MSI (s) (78:5C) [19:54:21:691]: WIN64DUALFOLDERS: Substitution in 'C:\Program Files (x86)\Service\Service.dll' folder had been blocked by the 1 mask argument (the folder pair's iSwapAttrib member = 0).
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.
MSI (s) (78:5C) [19:54:53:705]: Note: 1: 2727 2:
MSI (s) (78:5C) [19:54:53:706]: Doing action: RemoveExistingProducts
MSI (s) (78:5C) [19:54:53:706]: Note: 1: 2205 2: 3: ActionText
Action ended 19:54:53: InstallValidate. Return value 1.
MSI (s) (78:5C) [19:54:53:706]: Skipping RemoveExistingProducts action:
current configuration is maintenance mode or an uninstall
Action start 19:54:53: RemoveExistingProducts.
MSI (s) (78:5C) [19:54:53:706]: Doing action: InstallInitialize
MSI (s) (78:5C) [19:54:53:706]: Note: 1: 2205 2: 3: ActionText
Action ended 19:54:53: RemoveExistingProducts. Return value 0.
MSI (s) (78:5C) [19:54:53:708]: Machine policy value 'AlwaysInstallElevated' is 0
MSI (s) (78:5C) [19:54:53:708]: User policy value 'AlwaysInstallElevated' is 0
I have below code to restart service on failure. do u think it causes issue?
<util:ServiceConfig xmlns:util="http://schemas.microsoft.com/wix/UtilExtension"
FirstFailureActionType="restart"
SecondFailureActionType="restart"
ThirdFailureActionType="restart" />
Issue root cause
I see that old version is not getting deleted during upgrade. Hence created a new question here Wix installer upgrade with same "upgrade code" ID shows privilege error prompt
Issue resolved. Culprit was below code
<util:ServiceConfig xmlns:util="http://schemas.microsoft.com/wix/UtilExtension"
FirstFailureActionType="restart"
SecondFailureActionType="restart"
ThirdFailureActionType="restart" />
I have added delay as follow, and everything working like charm now.
RestartServiceDelayInSeconds="60"
Thanks to someone who thought the need for RestartServiceDelayInSeconds. Great thinking during ServiceConfig utility development
So I was installing MongoDB and this message kept popping up. I tried clicking on OK thinking that it would reboot the system but nothing happened. Then I turned off my internet and retried. It worked. This was weird but that's how my problem got resolved.

Permissions problem with Wix Custom Action and Burn bootstrapper

I have a package that needs to be installed with elevated administrator privileges. However, this installer includes an uninstall custom action to run a clean-up executable, which must be run as the local user.
This all works fine for the generated MSI (install and uninstall), but when I wrap the MSI up in a Burn bootstrapper, the uninstall custom action is instead run as the administrator - and hence fails...
My application must be installed “perMachine”, and so in my Product.wxs I have my package setup with
InstallPrivileges="elevated"
InstallScope="perMachine"
However, this application's uninstaller includes an uninstall custom action to run a clean-up executable, which must be run as the local user (since it looks for a file in the user’s App-Data). So I’ve set the CustomAction to
Impersonate="yes" Execute="immediate"
And have:
<InstallExecuteSequence>
<Custom Action="UninstallCleanup" Before="RemoveFiles">
(NOT UPGRADINGPRODUCTCODE) AND (REMOVE="ALL")
</Custom>
</InstallExecuteSequence>
This builds my MSI file, which I can then install on my machine. When I then run the uninstall, either via the Control Panel or manually (msiexec /x MyInstaller.msi /l* Testing.log), I am prompted for an admin password, the application is uninstalled, and the custom action is run as the local user. Everything perfect.
BUT I need to wrap this MSI up in a WiX Burn bootstrapper EXE that also installs pre-requisites (the VC runtime) before running my MSI package. Now when this Package Bundle is installed, and then uninstalled via the control panel, my MSI uninstall custom action is run as the administrator rather than the local user - and so fails.
In my Bundle.wxs file I have:
<PackageGroup Id="PP_Package">
<MsiPackage
Compressed="yes"
EnableFeatureSelection="no"
SourceFile="$(var.PP_MSI_PATH)"
Permanent="no"
DisplayInternalUI="no"
Visible="no"
Vital="yes">
<MsiProperty Name="INSTALLFOLDER" Value="[InstallFolder]" />
</MsiPackage>
</PackageGroup>
And
<PackageGroup Id="VCRedist">
<ExePackage Id="vcRedist_x86"
Cache="yes"
Compressed="yes"
PerMachine="yes"
Permanent="yes"
Vital="yes"
SourceFile="$(var.VCREDIST_X86_LOC)\$(var.VCREDIST_X86_FILE)"
Name="Redist\$(var.VCREDIST_X86_FILE)"
InstallCommand="/install /quiet /norestart"
Protocol="burn">
<ExitCode Value="1638" Behavior="success" />
<ExitCode Value ="3010" Behavior="forceReboot" />
</ExePackage>
</PackageGroup>
And then:
<Chain>
<PackageGroupRef Id="VCRedist" />
<RollbackBoundary Vital="yes" />
<PackageGroupRef Id="PP_Package" />
</Chain>
What have I got wrong? Is the issue something like: WiX Burn detects that the MSI is perMachine and so starts it using elevated admin, so that the custom action interprets Impersonate="yes" as meaning the administrator rather than the local user?
Any help, explanations and solutions would be most welcome.

WIX Bootstrapper uninstall without uninstalling MSI how to?

I'm building a WIX Bundle/Chain bootstrapper. It runs and installs like I specified.
I would like to be able to uninstall the bootstrapper without installing the installed MSI. How to accomplish that?
I'm using WIX 3.11.
Other posting here seem to have the opposite behaviour and demand. They seem to use other versions of wix (<=3.10).
Is there a way to accomplish that behaviour?
Some snippets:
...
</Chain>
TK
In your MsiPackage node, add the Permanent flag and set it to yes. When you uninstall your bootstrapper, the msi(s) set this way will remain installed on the machine.
<MsiPackage Id="MSI2KEEP"
Cache="no"
Compressed="yes"
Name="MSI2KEEP"
ForcePerMachine="yes"
DisplayInternalUI="no"
Vital="yes"
**Permanent="yes"**
SourceFile="$(var.MSI2KEEP.TargetPath)"
DisplayName="MSI 2 KEEP"
Description="MSI 2 KEEP" />

Burn - MsiPackage and Impersonation

I have an msi that allows the user to conditionally launch the installed application. The msi was created with Wix and includes the following xml statement:
<CustomAction Id='LaunchApplication' FileKey='foo.exe' ExeCommand='' Return="asyncNoWait" Impersonate="yes" />
The msi runs elevated, but the Impersonate option guarantees that the application is launched as the installing user.
The msi is included in my Burn package using the following statement:
<MsiPackage Id="FooMsi" SourceFile="$(var.Installer.TargetPath)" DisplayInternalUI="yes" Vital="yes" Permanent="no" />
However, Burn is elevated before the msi runs and therefore runs the application as Administrator.
Is there an impersonation option for Burn or do I have to launch the application from Burn instead?
Burn launches per-machine packages from an elevated helper process so MSI impersonates the elevated user. There's no way to tell MSI to impersonate another user and/or different permissions. You can use the LaunchTarget attribute of the WixStandardBootstrapperApplication element to launch a process from the unelevated Burn process.