WIX run vcredist_x64.exe on install - wix

I have an application compiled in VS 2015 and requires the VC++ Redistributable package in order to run properly. Prior to this latest build, we were using an older version of VS and simply used a merge module to handle the installation of the appropriate redist files. However, I noticed that when using the latest version of the merge modules for 2015 (Microsoft_VC140_CRT_x64.msm) that my application still wouldn't work out of the box. I did some digging and it appears that some things have changed with the latest version of the merge modules. It appears that Microsoft is now recommending to install the vcredist_x64.exe package directly instead of using merge modules.
So, I'm attempting to create a custom action to do this. I'm following a similar tutorial here, although adapting it for the VC Redistributable executable. The first thing I need to do is setup where the .exe file is going to be placed once installed:
<Directory Id='APPLICATIONROOTDIRECTORY' Name='MyApp'>
<Directory Id="VCREDISTDIR" Name="VCRedist">
</Directory>
</Directory>
Then, I need to add my files into a component group which will be installed as part of a hidden feature (as I want this to be automatically installed).
<ComponentGroup Id="VCRedist" Directory="VCREDISTDIR">
<Component Id="vcredist_x64.exe" Guid="-INSERT-GUID-HERE-" Win64="yes">
<File Id="VCREDISEXE" Name="vcredist_x64.exe" KeyPath="yes" Source="$(var.VCRedistSourceDir)" Checksum="yes"></File>
</Component>
</ComponentGroup>
And...
<Feature Id="VCRedistributable" Title="Visual C++ Runtime" AllowAdvertise="no" Display="hidden" Level="1">
<ComponentGroupRef Id="VCRedist" />
</Feature>
At this point, the vcredist_x64.exe should be copied to the end user's machine. Now, I need to create a custom action to launch the executable after the installation.
<CustomAction Id="InstallVCRedistributable"
FileKey="VCREDISEXE"
Execute="deferred"
ExeCommand="/silent"
Impersonate="no"
Return="check"/>
<InstallExecuteSequence>
<Custom Action="InstallVCRedistributable" Before="InstallFinalize">
<![CDATA[NOT REMOVE]]>
</Custom>
</InstallExecuteSequence>
I also include a status message to my UI so that I can see when the executable is being executed.
<UI>
<ProgressText Action="InstallVCRedistributable">Installing Visual C++ Redistributable for Visual Studio 2015</ProgressText>
</UI>
Now, when I run my installer it should launch the vcredist_x64.exe... and it does... but then during the installation of that executable it gets hung up. I get a popup message that says there is a problem with this Windows Installer Package and that a program run as part of the setup did not complete. It then rolls-back my main application installation and never gets installed. Can anyone explain why this is happening and how to fix it? Thanks!

I found this question and tried it myself, being in the same situation. I found the installer error you're running into was/is Error 1618: "Another installation is already in progress." It seems that running the vc_redist installer inside your own installer simply won't work.
Your other options seem to be creating a bootstrapper as Patrick Allwood suggests above, or simply asking users to install the vc_redist package on their own before running your own installer. You can detect if the Universal C Runtime is already present by checking for ucrtbase.dll in C:\Windows\System32:
<Property Id="UCRTINSTALLED">
<DirectorySearch Id="UCRTSystemSearch" Path="[WindowsFolder]System32" Depth="0">
<FileSearch Id="UCRTFileSearch" Name="ucrtbase.dll" MinVersion="10.0.10240.16389" />
</DirectorySearch>
</Property>
If you only have a 32-bit installer, you can also use the [SystemFolder] property directly.
EDIT: As Kevin Smyth mentioned, the version of ucrtbase.dll is giving weird issues - reporting version 2.X to some tools, and version 10.Y to other tools. You can remove the MinVersion property if you just want to check for the existence of ucrtbase.dll.

I think the correct approach to take when having prerequisites that have their own installers is to create a WiX bootstrapper bundle, which runs through each installer in turn. This handles things like rollbacks on install failures, etc, which running custom actions from within an installer does not.
A barebones sample can be seen here, you add <MsiPackage> and <ExePackage> in the Chain element in the order you need them to install.

I was facing a similar problem (fully described in this closed question, which actually redirected me here). I was able to solve it, inspired by this entry about running the application after setup.
The key part is basically to add a final step to the UI that launches the vcredist installer:
<UI Id="UI_Main">
<!-- ...... -->
<Publish Dialog="ExitDialog"
Control="Finish"
Event="DoAction"
Value="InstallVCRedistributable">1</Publish>
</UI>
Regarding the custom action:
<CustomAction Id="InstallVCRedistributable"
FileKey="VCREDISEXE"
ExeCommand="/install /passive /norestart"
Impersonate="yes"
Return="asyncNoWait" />

Related

VC redistributable fails to install when executed within an MSI [duplicate]

I have an application compiled in VS 2015 and requires the VC++ Redistributable package in order to run properly. Prior to this latest build, we were using an older version of VS and simply used a merge module to handle the installation of the appropriate redist files. However, I noticed that when using the latest version of the merge modules for 2015 (Microsoft_VC140_CRT_x64.msm) that my application still wouldn't work out of the box. I did some digging and it appears that some things have changed with the latest version of the merge modules. It appears that Microsoft is now recommending to install the vcredist_x64.exe package directly instead of using merge modules.
So, I'm attempting to create a custom action to do this. I'm following a similar tutorial here, although adapting it for the VC Redistributable executable. The first thing I need to do is setup where the .exe file is going to be placed once installed:
<Directory Id='APPLICATIONROOTDIRECTORY' Name='MyApp'>
<Directory Id="VCREDISTDIR" Name="VCRedist">
</Directory>
</Directory>
Then, I need to add my files into a component group which will be installed as part of a hidden feature (as I want this to be automatically installed).
<ComponentGroup Id="VCRedist" Directory="VCREDISTDIR">
<Component Id="vcredist_x64.exe" Guid="-INSERT-GUID-HERE-" Win64="yes">
<File Id="VCREDISEXE" Name="vcredist_x64.exe" KeyPath="yes" Source="$(var.VCRedistSourceDir)" Checksum="yes"></File>
</Component>
</ComponentGroup>
And...
<Feature Id="VCRedistributable" Title="Visual C++ Runtime" AllowAdvertise="no" Display="hidden" Level="1">
<ComponentGroupRef Id="VCRedist" />
</Feature>
At this point, the vcredist_x64.exe should be copied to the end user's machine. Now, I need to create a custom action to launch the executable after the installation.
<CustomAction Id="InstallVCRedistributable"
FileKey="VCREDISEXE"
Execute="deferred"
ExeCommand="/silent"
Impersonate="no"
Return="check"/>
<InstallExecuteSequence>
<Custom Action="InstallVCRedistributable" Before="InstallFinalize">
<![CDATA[NOT REMOVE]]>
</Custom>
</InstallExecuteSequence>
I also include a status message to my UI so that I can see when the executable is being executed.
<UI>
<ProgressText Action="InstallVCRedistributable">Installing Visual C++ Redistributable for Visual Studio 2015</ProgressText>
</UI>
Now, when I run my installer it should launch the vcredist_x64.exe... and it does... but then during the installation of that executable it gets hung up. I get a popup message that says there is a problem with this Windows Installer Package and that a program run as part of the setup did not complete. It then rolls-back my main application installation and never gets installed. Can anyone explain why this is happening and how to fix it? Thanks!
I found this question and tried it myself, being in the same situation. I found the installer error you're running into was/is Error 1618: "Another installation is already in progress." It seems that running the vc_redist installer inside your own installer simply won't work.
Your other options seem to be creating a bootstrapper as Patrick Allwood suggests above, or simply asking users to install the vc_redist package on their own before running your own installer. You can detect if the Universal C Runtime is already present by checking for ucrtbase.dll in C:\Windows\System32:
<Property Id="UCRTINSTALLED">
<DirectorySearch Id="UCRTSystemSearch" Path="[WindowsFolder]System32" Depth="0">
<FileSearch Id="UCRTFileSearch" Name="ucrtbase.dll" MinVersion="10.0.10240.16389" />
</DirectorySearch>
</Property>
If you only have a 32-bit installer, you can also use the [SystemFolder] property directly.
EDIT: As Kevin Smyth mentioned, the version of ucrtbase.dll is giving weird issues - reporting version 2.X to some tools, and version 10.Y to other tools. You can remove the MinVersion property if you just want to check for the existence of ucrtbase.dll.
I think the correct approach to take when having prerequisites that have their own installers is to create a WiX bootstrapper bundle, which runs through each installer in turn. This handles things like rollbacks on install failures, etc, which running custom actions from within an installer does not.
A barebones sample can be seen here, you add <MsiPackage> and <ExePackage> in the Chain element in the order you need them to install.
I was facing a similar problem (fully described in this closed question, which actually redirected me here). I was able to solve it, inspired by this entry about running the application after setup.
The key part is basically to add a final step to the UI that launches the vcredist installer:
<UI Id="UI_Main">
<!-- ...... -->
<Publish Dialog="ExitDialog"
Control="Finish"
Event="DoAction"
Value="InstallVCRedistributable">1</Publish>
</UI>
Regarding the custom action:
<CustomAction Id="InstallVCRedistributable"
FileKey="VCREDISEXE"
ExeCommand="/install /passive /norestart"
Impersonate="yes"
Return="asyncNoWait" />

WIX installer unresolved reference to custom action that uninstalls ClickOnce

I have a Wix installer for an add-in, that was previously installed via ClickOnce, and while running the MSI, it should uninstall the ClickOnce deployment.
Wunderlist was kind enough to share their code on github, but the support on it is dead, so I'm coming here and trying to generalize the question, while also including the link to anybody who searches for this on Stackoverflow.
Basically I included this snippet in my Product.wxs file:
<!--ClickOnce Uninstaller-->
<Property Id="CLICKONCEAPPNAME" Value="Application Name" />
<CustomAction Id="UninstallClickOnce"
BinaryKey="ClickOnceUninstaller"
DllEntry="UninstallClickOnce"
Return="ignore" />
<InstallExecuteSequence>
<Custom Action="UninstallClickOnce" Before="InstallFinalize">NOT Installed</Custom>
</InstallExecuteSequence>
<!--ClickOnce Uninstaller-->
I added the references to the UninstallClickOnce project that hosts the ClickOnceUninstaller custom action.
However, when trying to build the installer it shows the following message on the CustomAction tag:
Unresolved reference to symbol 'Binary:ClickOnceUninstaller' in section 'Product:*'
Any obvious thing I'm missing?
Here's the link to the github project: https://github.com/6wunderkinder/Wunder.ClickOnceUninstaller

Is there a way to run uninstallers from an installer in WiX?

I have a WiX based installer for a suite of applications. It replaces a bunch of old installers where each application in the suite had its own InstallShield based installer.
I would like the WiX installer to find any old InstallShield based installations and run their respective uninstallers. I have tried this:
<Property Id="OLD_APPLICATION_A_UNINSTALLSTRING">
<RegistrySearch Id="OldAppAUninstallString" Root="HKLM"
Key="SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{$(var.OldAppAInstallerGUID)}"
Name="UninstallString" Type="raw"/>
</Property>
<InstallExecuteSequence>
<Custom Action="UninstallAppA" Before="InstallInitialize">
NOT Installed AND OLD_APPLICATION_A_UNINSTALLSTRING
</Custom>
</InstallExecuteSequence>
<CustomAction Id="UninstallAppA" Directory="System32"
ExeCommand="[OLD_APPLICATION_A_UNINSTALLSTRING] /qn" Execute="immediate" Return="check"/>
This results in a failed installation and error status 1618: "Another installation is already in progress. Complete that installation before proceeding with this install." Only one other installation is in progress, this installation...
Is there a way to run uninstallers from an installer in WiX?
I also have a bootstrapper and maybe I should run these uninstallations from there somehow. But I want to run them as late as possible in case the user cancels the installation. If that happens it doesn't look too good if the old application suite is gone...
In MSI there is a mutex that prevents two installation transactions (execute sequence) running at the same time hence your error.
You can use additional Upgrade elements to seek them out by UpgradeCode / Version / Lanugage and cause their removal during your installation transaction.

Wix - third party software reinstalls everytime app is run

My application installs the DesKey Dk2 dongle drivers if they are not installed or are lower than a perticular version. One of the user is complaining that whenever he runs the application from start menu shortcut, DK2 installation starts and then application is launched. Nobody else is facing this issue.
I am indtalling Dk2 as custom action in Wix script as below. lets say DK2 is represented as ABC:
<DirectoryRef Id="TARGETDIR">
<Directory Id="ABCRedistDirectory" Name="ABCDrivers">
<Component Id="ABCRedist" Guid="*">
<File Id="ABC_EXE" Source="$(var.TargetDir)ABC.exe" KeyPath="yes" Checksum="yes"/>
</Component>
</Directory>
</DirectoryRef>
<Property Id="DK2_VERSION">
<RegistrySearch Id="Dk2_Version"
Root="HKLM"
Key="SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\DESkey DK2 Uninstall"
Name="DisplayVersion"
Type="raw" />
</Property>
<Feature Id="ABCRedist" Title="ABC drivers" AllowAdvertise="no" Display="hidden" Level="1">
<ComponentRef Id="ABCRedist"/>
</Feature>
<CustomAction Id="InstallDK2Drivers" FileKey="ABC_EXE" ExeCommand="" Execute="deferred" Impersonate="no" Return="check"/>
<InstallExecuteSequence>
<Custom Action="InstallDK2Drivers" Before="InstallFinalize">
<![CDATA[NOT DK2_VERSION OR DK2_VERSION < "7.34.0.57"]]>
</Custom>
</InstallExecuteSequence>
The warning in Windows Event viewer points to main executable, which is below:
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLLOCATION" Name="FolderName">
<Directory Id ="MyFolder" Name="MyApp">
<Component Id ="MyApp.exe" Guid="*">
<File Id="MyApp.exe" Source ="$(var.TargetDir)MyApp.exe" KeyPath="yes" Checksum ="yes" />
<Shortcut Id="MyAppStartMenuShortcut" Name="My App" Directory="ProgramMenuDir" Icon="MyAppIcon.exe" WorkingDirectory="MyFolder" Advertise="yes"></Shortcut>
<Shortcut Id="MyAppDesktopShortcut" Name="My App" Directory="DesktopFolder" Icon="MyAppIcon.exe" WorkingDirectory="MyFolder" Advertise="yes"></Shortcut>
</Component>
...
Now it is not happening on other machines so I am not able to diagnose. Can anybody point out any obvious mistake? What can I do to diagnose this on customer's machine i.e. how to get logs when installing .exe, .dll, some third party installers like VC100 CRT and VC100 MFC and .Net 4.0 bootstrapper?
Thanks in advance.
I can't tell from your post if the 3rd party ABC product that you're using is the same one that is repairing, or maybe the client doesn't know and you're assuming that it is your ABC thing. There's no indication in that WiX fragment exactly how you're installing the ABC thing, all you show is that it's copied to disk, there's no clue how you are running it to get it installed, and no shortcuts either.
What's happening in general seems to be that the other product is going into repair mode. There should be MsiInstaller entries in the Application Event Log that say something about whatever is wrong, referencing component ids, products, and maybe file names or registry entries.
Your setup may have a conflict with that other install. It's unlikely to be anything to do with your shortcut except that your shortcut is advertised, so it goes off into a component feature check, and is apparently finding that you are sharing something with that other app, and now it needs repairing. If the 3rd party app that repairs is not your ABC thing then you won't be able to reproduce the issue unless you also install that 3rd party thing and find out what you're sharing with it, perhaps in the wrong way.
Is this some sort of bit-torrent component? I see an abc project on sourceforge.net with Python dll's, some visual C++ runtimes included as well as other stuff. This is by no means a properly constructed package, and it could trigger the self-repair problems seen on that particular computer.
To debug this would require to see what entries exist in the Windows Event log - it will specify what MSI component triggered the repair. The error could still be in other packages since a COM call from the embedded components in this abc package, could trigger a repair in any MSI package installed on the system. As could taking over a file association associated with torrent files.
Right click My Computer
Select Manage
Event Log -> Windows Logs -> Programs
In this log you will find entries starting with "Description: Detection of product..." with id 1001 or 1004. Here is a sample:
Event ID: 1001
Description: Detection of product "{4ED0C75A-8BC5-4520-B9C7-76968FD5677F}", feature "Test" failed during request for component "{A7B09747-E527-4E1B-AE51-323CD636210F}"
This information is enough to determine what package triggered the self-repair. Please provide this information and we can take it from there.
I extracted the above sample information from Stefan Krüger's MSI FAG at installsite.org.
You are using advertised shortcuts. In your Shortcut elements, set Advertise="no" or remove the Advertise attribute completely.
For more information, see this SO answer and msdn.

Install Driver using Executable

I am working on writing a WiX installer that needs to install a driver as a prerequisite. There is an executable that needs to be run that installs the driver on the PC. I don't want to install this executable on the host machine. There is both a x64 and x86 version and, depending on the platform, one or the other needs to be installed.
The executable is currently run using the command line:
C:\Comp\code\install\canned\tabload\x86>tabload install "*tab1394" "C:/Comp/code/install/canned/tab1394/x86"
The last argument is the location of the .cat, .sys and .inf files for the driver
The current code I have is:
<!-- Install correct device driver -->
<?if $(var.Platform) = x64?>
<Property Id="Win64">1</Property>
<?else?>
<Property Id="Win64">0</Property>
<?endif?>
<Binary Id="tabload64EXE" SourceFile="C:/Tableau/code/install/canned/tabload/x64/tabload.exe" />
<Binary Id="tabload32EXE" SourceFile="C:/Tableau/code/install/canned/tabload/x86/tabload.exe" />
<CustomAction Id="LaunchFile64"
BinaryKey="tabload64EXE"
ExeCommand='tabload "*tab1394" "C:/comp/code/install/canned/tab1394/x64 "'
Return="asyncNoWait" />
<CustomAction Id="LaunchFile32"
BinaryKey="tabload32EXE"
ExeCommand='tabload install "*tab1394" "C:/comp/code/install/canned/tab1394/x86 "'
Return="asyncNoWait" />
<InstallExecuteSequence>
<Custom Action="LaunchFile64" After="InstallFinalize">Win64</Custom>
<Custom Action="LaunchFile32" After="InstallFinalize">NOT Win64</Custom>
</InstallExecuteSequence>
I've looked at the tables in Orca. The Win64 property seems to be getting set correctly. The custom actions and binaries appear and the Target for the custom action is the indicated command line. The custom action is type 196 and I can't find any documentation for that online. When I build and install the installation package, the program is installed but the driver component is not installed. Please advise on how to remedy the situation.
Thanks!
The MSI SDK CustomAction table has the links to decipher the Type. I'm going to guess the root issue is that the custom actions are not deferred so they are not be executed by the elevated transaction.