WIX. How to not reinstall a feature during repair? - wix

In WIX I'd like a feature to be installed and uninstalled normally but not to be touched during repair.
I was not able to find a condition which would allow me to do this.
My attempts has failed: the feature is reinstalled on repair (what I do not need) or is not uninstalled.
This is a sample that I tried last:
<Feature Id="aFeature" Title="A Features" Level="1">
<ComponentRef Id="aComponent" />
<Condition Level="0">
<![CDATA[WixUI_InstallMode="Repair"]]>
</Condition>
</Feature>
What is the right condition to uninstall but not re-install during repair?
Or what did I do wrong?

This works for me:
<Feature Id="aFeature" Title="A Features" Level="1">
<ComponentRef Id="aComponent" />
<Condition Level="0">
<![CDATA[REINSTALL<>""]]>
</Condition>
</Feature>
This way during Repair the feature is ignored and not touched, but normally uninstalled

The only way I can think of is to give all the components in that feature an empty guid, that's the signal to Windows Installer not to do anything with them, such as repair them, patch them, uninstall them. If the product is already shipped it's too late for that. However that's a drastic step that is normally necessary only when you want to install some things for temporary use and then delete them. So you are fighting the framework here. It's look like you have a problem that disabling feature repair might solve, so why not describe the problem to see if there is another solution?

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" />

Custom Action for Feature in WIX

I am trying to execute an EXE file through my installation and this file should be installed if the related feature will be installed in the feature tree.
I have two questions :
1-How to relate the Custom Action to this feature."The condition"
2- How I can include this exe file in the generated file. "This EXE File is a SQL Installation which I already made in WIX BOOTSTRAPPER "
http://apprize.info/web/wix/13.html
and my code is
<Feature Id="SubFeature1" Title="SQL Installation" Level="1" >
<ComponentRef Id="SubComponent1"/>
</Feature>
<Feature Id="SubFeature2" Title="Second Subfeature" Level="1" >
<ComponentRef Id="SubComponent2"/>
<!-- <Condition Level="0">IISMAJORVERSION=""</Condition> -->
</Feature>
</Feature>
<CustomAction Id="CreateSQLINSTALLER" Directory="BMSS4_Installer"
Execute= "deferred" Impersonate="no" Return="ignore"
ExeCommand="[BMSS4_Installer]Sql_Installation_Test1.exe -install" />
<InstallExecuteSequence>
<Custom Action="CreateSQLINSTALLER" Before="InstallFinalize"><![CDATA[(&SubFeature1)]]></Custom>
</InstallExecuteSequence>
the Sql_Installation_Test1.exe is included in the main folder so BMSS4_Installer..
But is it right to use it direclty like that in Directory tag om CustomAction !!
Feature conditions are documented here:
https://msdn.microsoft.com/en-us/library/aa368012(v=vs.85).aspx
in the action state of the feature. Basically you use a condition such as:
&featurename=3
where 3 is INSTALLSTATE_LOCAL, as there in the documentation. There are limits on where the condition can be used, the main one being after CostFinalize.
It's not clear if you are installing some version of SQL itself, but that would have its own install and wouldn't need repackaging, and it would be a prerequisite installed with Burn, for example. If it's a separate MSI setup of yours, again a Burn package would probably be the best way to install it and your other MSI.

WIX run vcredist_x64.exe on install

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" />

Install merge module for all users using WiX

I created an Installer using WiX to install a VSIX along with two dependent components. These two components were available to me in the form of Merge Modules. Below is the code where I used the merge modules in my code:
<DirectoryRef Id="TARGETDIR">
<Merge Id="MergeModuleID1" SourceFile="MergeModule1.msm" DiskId="1" Language="0"/>
<Merge Id="MergeModuleID2" SourceFile="MergeModule2.msm" DiskId="1" Language="0" />
</DirectoryRef>
and I've referred these merge modules as:
<Feature Id="ProductFeature" Title="Title" Level="1">
<ComponentRef Id="VSPackage"/>
<ComponentRef Id="ApplicationShortcut"/>
<ComponentRef Id="DesktopShortcut"/>
<ComponentRef Id="LicenseComp"/>
<MergeRef Id="MergeModuleID1"/>
<MergeRef Id="MergeModuleID2"/>
</Feature>
The problem I'm facing is, that my VSIX is installed to all the user accounts on the machine, but these merge modules are not, they're installed only on the user account where the product is installed. On other user accounts, an installation dialog appears, which I believe is installing these merge modules, after which everything works fine.
How do I make these merge modules to be installed to all users?
P.S: ALLUSERS property in both the MSI and merge modules are set to '1'.
You may need to clarify that question somewhat. Merge modules are not installed, just the files, so you mean the files in merge modules are going somewhere incorrect, yes? Also, files are not installed on a user account they got to a location on disk.
Guessing my way through this, you're probably saying that the files get installed to somewhere like the User's Application Data location for the installing user. If that's what the merge modules specify in their internals, that's normal. You can obviously install files to the current user's application data folder even if you're doing a per machine install. I can't say if those merge modules are correctly designed or not, but if they are then:
The initial install will put those files in the installing users file location.
If another logs on and uses a shortcut and your MSI is correctly designed, the install-on-demand feature will install those files for that user in that user's folder, maybe asking for the original install media. That's the way this is designed to work because:
a) There is no mechanism that that allows a file to be installed simultaneously to all user file locations on the system, and it makes no sense anyway if they never use the app.
b) What happens if you create a new user account AFTER the product has been installed? The file will not be in that user's location, however the install on demand scheme guarantees that this new user will get the file in their location if they log on and use the app.
The short answer is that this is probably all working as intended.
Setting ALLUSERS is fine.
What you've described looks like "advertising".
To remove advertising for the Merge Modules, add AllowAdvertise="no" to the Attributes of the Feature containing the MergeRef element :
<Feature Id="ProductFeature" Title="Title" AllowAdvertise="no" Level="1">
<ComponentRef Id="VSPackage"/>
<ComponentRef Id="ApplicationShortcut"/>
<ComponentRef Id="DesktopShortcut"/>
<ComponentRef Id="LicenseComp"/>
<MergeRef Id="MergeModuleID1"/>
<MergeRef Id="MergeModuleID2"/>
</Feature>

Sequencing Components in Feature Element

I want to replace a file that has been installed by my installer. In the following code the "OneCoreFiles" component should install the files first time( which is working) and the component "ConfigCopyFile" should replace that config file.
But the code is not working as expected. The component 'ConfigCopyFile' is getting executed first and then the 'OnecoreFiles'. I want it to work the other way.
I am still learning WIX and thought that the components in Feature elements are executed in the order in which they are declared.
Code Snippet:
<Component Id="ConfigCopyFile" Guid="{98E61055-5A84-4003-90D1-7A67677D7465}">
<Condition>CONFIGFILEEXISTS</Condition>
<CopyFile Id="ConfigFileId" SourceProperty="CONFIGFILEEXISTS" DestinationProperty ="INSTALLDIR"/>
</Component>
<Feature Id="ProductFeature" Title="OneCore Features" Level="1">
<ComponentRef Id="LogEntries" />
<ComponentGroupRef Id="OneCoreFiles" />
<ComponentRef Id="AppDBConfiguration" />
<ComponentRef Id="SqlServerConfiguration" />
<ComponentRef Id="OracleConfiguration" />
<ComponentRef Id="IISConfiguration" />
<ComponentRef Id="ConfigCopyFile" />
</Feature>
This must be quite simple to solve. Am I missing something. Please advice.
You are thinking of WiX in the wrong way. It's not a scripting language. It's a way of representing Windows Installer databases which are declarative in nature not imperative. If I list a bunch of components and files it's non deterministic the order the files will be copied. I'm only saying that these files need to be installed not how to install them.
Windows Installer does expose sequence tables which drive the order of things ( such as create folders then copy files ) but it doesn't micromanage to the level of copy this file before that file.
Suggested InstallExecute Sequence
InstallExecuteSequence Table