MsiPackage conditional install: Don't uninstall if it detects package is already installed - installation

I'm using Wix Bootstrapper and want to install a few applications through .msi packages alongside my main application. These applications may be installed in the target PC already so I need to detect these first and skip installation if they are already installed. Furthermore, during uninstallation, these applications should not be uninstalled since the Wix Bootstrapper did not install them.
I've tried to use the InstallCondition attribute but (as expected) it uninstalls if it detects the application is already installed.
My Bundle.wxs looks like this:
...
<Bundle>
<util:FileSearch Id='CheckApplicationX' Path='[ProgramFilesFolder]ApplicationX\ApplicationX.exe' Variable='ApplicationXFile' Result='exists' />
<Chain DisableRollback="yes">
...
<MsiPackage Id="InstallApplicationX" Vital="yes" Compressed="yes" DisplayInternalUI="no" EnableFeatureSelection="no" SourceFile="..\application-x.msi" Name="Application X" DisplayName="Application X" ForcePerMachine="yes" InstallCondition="NOT ApplicationXFile" />
...
</Chain>
</Bundle>
...
Any help/hints are appreciated!

You can try to detect if the applications are installed by looking in the Windows Registry and try to identify if there are "traces" left by those applications.
You can use the RegistrySearch tag to perform a conditional evaluation of the registry entries you're looking for and then deny the installation.
There's an example on Wix Website available at this link.
The following example shows how you can define if .NET 2.0 is installed on the target machine
<Property Id="NETFRAMEWORK20">
<RegistrySearch Id="NetFramework20"
Root="HKLM"
Key="Software\Microsoft\NET Framework Setup\NDP\v2.0.50727"
Name="Install"
Type="raw" />
</Property>
<Condition Message="This application requires .NET Framework 2.0. Please install the .NET Framework then run this installer again.">
<![CDATA[Installed OR NETFRAMEWORK20]]>
</Condition>

Related

how to give optional install for multiple msi packages in single WiX installer?

I have multiple packages that I want to install using single installer. Two of them are MSI packages, other two are exe files. I am using WiX to make single installer to install all four packages, and want to give user option to choose which one (or more) they want to install.
Here, One MSI package is for WPF Desktop application that I am developing, other 3 packages are add-on features that I want to give option to select/deselect.
So, far I am able to install all four of them using WiX BootStrapper. But I could not find how to give select options to user during installation.
Also I am using Visual Studio 2019 IDE for development.
Assuming your using the standard bootstrapper application you need to bring in a copy of your favorite Theme.wxl:
<BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.HyperlinkLicense" >
<bal:WixStandardBootstrapperApplication LicenseFile="Resources\EULA.rtf" LogoFile="Resources\Icon.png" LicenseUrl="http://www.google.com" LocalizationFile="Resources\HyperlinkTheme.wxl" ThemeFile="Resources\HyperlinkTheme.xml" SuppressOptionsUI="yes" />
</BootstrapperApplicationRef>
Then in the Theme wxs add a button:
<Text X="11" Y="175" Width="130" Height="20" FontId="3" Visible="yes" DisablePrefix="yes">Install Something</Text>
<Checkbox Name="INSTALLSOMETHING" X="140" Y="175" Width="-11" Height="20" TabStop="yes" FontId="3" Visible="yes"></Checkbox>
Then in your bundle.wxs declare a variable so it can be passed as an argument for silent installations:
<Variable Name="INSTALLSOMETHING" bal:Overridable="yes" Type="string" Value="" />
And finally use it's value to control the installation of something.
<ExePackage Id="Something" SourceFile="Something.exe" InstallCondition="(INSTALLSOMETHING="1") or (INSTALLSOMETHING="True")" />
Rinse and repeat 3 more times.

Major Upgrade in WiX installer not working following a UIRef change

I have changed a UIRef tag between versions of my deployment.
from Version 1.0: <UIRef ID="WixUI_FeatureTree" />
to Version 2.0: <UIRef ID="WixUI_Advanced" />
Wix Version 3.6
Now, when I run the Version 2.0 installer, it does not detect
the previous version, so instead of uninstalling during the upgrade
it installs a new version next to the existing version.
Intermediate versions upgraded fine (1.0->1.1->1.2).
The major changes in 2.0 are:
A new sub-feature under the main
Change to the UIRef from WixUI_FeatureTree, to WixUI_Advanced
to allow deployment to select from 'AllUsers' and 'Single User'
Remove Existing Products is defined as:
<InstallExecuteSequence>
<RemoveExistingProducts After='InstallInitialize' />
<Custom Action=...
...
My product is defined as:
#UpgradeCode# is consistent between versions
#ProductId# is changed between versions
<Product Id="#ProductId"
UpgradeCode="#UpgradeCode#"
Name="!(loc.ApplicationName)"
Language="1033"
Codepage="1252"
Version="2.0.0"
Manufacturer="!(loc.Manufacturer)">
<Package
Id="*"
InstallerVersion="300"
InstallPrivileges="elevated"
Languages="1033"
Compressed="yes"
InstallScope="perMachine"
Manufacturer="!(loc.Manufacturer)"
SummaryCodepage="1252"
Platform="x86"
Description="!(loc.ApplicationName)"/>
<Upgrade Id="#UpgradeCode#">
<UpgradeVersion OnlyDetect="no" Property="PREVIOUSFOUND"
Minimum="1.0.0" IncludeMinimum="yes"
Maximum="2.0.0" IncludeMaximum="no"/>
</Upgrade>
I am wondering if there is something that I can do
to force the installer to check the upgrade and perform
remove of previous version that is no longer being handled
following my changes.
In the build log I noticed:
MSI (c) (6C:C4) [12:04:44:624]: FindRelatedProducts: current install is per-user. Related install for product '{PRODUCT-GUID }' is per-machine. Skipping...
Action ended 12:04:44: FindRelatedProducts. Return value 1.
I had removed:
<Product ... InstallScope="perMachine" ... />
when upgrading versions.
I did not realize that upgrade matching included the InstallScope Property of Product.
I can still install per-user using <UIRef Id="WixUI_Advanced" />, so this property does not seem to affect the selection of PerMachine or PerUser, so I have put it back in. Upgrade now works again.

WIX public properties displayed on the UI

We have an installer created using WIX. As part of this install we would like to show the currently selected installation path. I thought this would be much easier than it is, apparently. I have tried using the a public property "INSTALLDIR" (I know we're not using Installshield, this value is a directory ID.)
<Directory Id="INSTALLDIR" Name="AcmeInc">
I can also see where INSTALLDIR gets set when running the install
MSI(EC:6C) Dir (target): Key: INSTALLDIR , Object: C:\Program Files\AcmeInc\
but when I try to show this on the UI using a Text attribute I get "...\." which doesn't even look to be a relative path.
I know there has got to be something simple I'm missing here.
Assuming you're using WiX 3.5 and the MajorUpgrade element - the following should work (I usually use APPLICATIONFOLDER instead of INSTALLDIR - but they should be interchangeable).
First, let's set ARPINSTALLOCATION as described on http://robmensching.com/blog/posts/2011/1/14/ARPINSTALLLOCATION-and-how-to-set-it-with-the-WiX-toolset
<SetProperty Id="ARPINSTALLLOCATION" Value="[INSTALLDIR]" After="CostFinalize" />
Now lets set the selected installation folder to the previous installation folder, if one previously existed that is.
<Property Id="INSTALLDIR" Secure="yes">
<RegistrySearch Id="FindInstallLocation"
Root="HKLM"
Key="Software\Microsoft\Windows\CurrentVersion\Uninstall\[WIX_UPGRADE_DETECTED]"
Name="InstallLocation"
Type="raw"
Win64="yes" />
</Property>
And during the UI sequence, we want this value to be set 'early'
<InstallUISequence>
<AppSearch After="FindRelatedProducts"/>
</InstallUISequence>

How to change the Windows service startup type in a WiX installer

We need to modify the Startup type of our Windows service from "Automatic" to "Automatic Delayed Start". How do I do this?
My code is like this:
<ServiceInstall
Id="WinServiceInstall"
Name="ServiceManager"
DisplayName="ServiceManager"
Type="ownProcess"
Start="auto"
ErrorControl="normal"
Vital ='yes'
Description ='Monitoring and running the jobs'
Account="[SERVICEACCOUNT]"
Password="[SERVICEPASSWORD]">
<util:ServiceConfig
FirstFailureActionType="restart"
SecondFailureActionType="restart"
ThirdFailureActionType ="restart"
cRestartServiceDelayInSeconds ="10" />
</ServiceInstall>
And how do I set the Restart service time? I would like to set Restart service after 2 minutes if failed.
Place a ServiceConfig element within the ServiceInstall element.
<ServiceConfig DelayedAutoStart="yes" OnInstall="yes" OnReinstall ="yes" />
If you need to support really old versions of Windows, then you will need to set it with a reg-value, because MSI < 5.0 doesn't recognize this option with ServiceConfig. Otherwise, you should use the ServiceConfig method.
<RegistryValue Root="HKLM" Key="SYSTEM\CurrentControlSet\Services\[ServiceName]"
Type="integer" Name="DelayedAutostart" Value="1"/>
I put this in the same component as the ServiceInstall, and everything seems to work fine. I imagine you could do the same thing for the service restart time.

Install a pfx certificate in a users store in Windows using WiX

Please, can someone provide me with a WiX snippet or solution for the mentioned scenario. I need to include the pfx file in the WiX msi and the user will download my msi to his machine via the internet explorer and Click install and I need also the certificate to be installed on his machine.
You need the Certificate element. It is part of the IIS extension for wix, but can be used for non-IIS related installations also.
You need to
declare a prefix for the iis namespace, for
example like this in the root Wix element:
<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'
xmlns:iis='http://schemas.microsoft.com/wix/IIsExtension'>
Embed the PFX file as a binary
stream in your install package. Add
a Binary element under the
product element like this:
<Binary Id="MyCertificateBinaryStream"
SourceFile="c:/path/to/mycertificate.pfx" />
Declare a component with a <iis:Certificate> element, for
example like this. Look at the
documentation, you need to fill in some
more attributes. Note that you don't need CertficatePath if you use the BinaryKey attribute.
<Component Id="MyCertificateComponent" Guid="MY-GUID-HERE">
<iis:Certificate Id="MyCertificate"
BinaryKey="MyCertificateBinaryStream"
... some more attributes ...
/>
</Component>
Activate the IIS extension by adding
the option -ext WixIISExtension
option when invoking the wix command line tools. If you use visual studio, this is just a matter of adding a reference in your wix project to WixIISExtension.
To expand on the answer a little, the following set of attributes worked for me:
<iis:Certificate
Id="My.Certificate"
StoreName="root"
Overwrite="yes"
Name="My Friendly Certificate Name"
Request="no"
BinaryKey="MyCertificate.Binary"
StoreLocation="localMachine" />
Where the <Product> element contained a <Binary> child as follows:
<Binary
Id="MyCertificate.Binary"
SourceFile="$(var.ProjectDir)MyCertificate.pfx" />
(I included the PFX file within my WiX project).

Resources