WIX run vcredist_x64.exe on install

andyopayne picture andyopayne · Jan 15, 2016 · Viewed 7.3k times · Source

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!

Answer

Ganon11 picture Ganon11 · Feb 10, 2016

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.