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

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.

Related

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

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>

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.

Executing an EXE file in WiX

I try to execute an EXE file from an MSI file in WiX, but I got 1603 error when doing InitializeSetup.
Action ended 12:09:54: InstallValidate. Return value 1.
Action start 12:09:54: InstallInitialize.
Action ended 12:09:54: InstallInitialize. Return value 3.
Action ended 12:09:54: INSTALL. Return value 3.
What is wrong in this WiX Script?
<Product Name='something' Id='11934d63-12d1-4792-829e-046de3bb987e'
UpgradeCode='{a101616a-365c-44a7-bfcb-fafb356c2ea1}'
Language='1033' Version='8.3.4' Manufacturer='something2'>
<Package Id='*' InstallerVersion='200' Compressed='yes' />
<Binary Id="Instalator.exe" SourceFile="d:\Instalator.exe"/>
<CustomAction Id="LaunchFile" BinaryKey="Instalator.exe" ExeCommand="" Execute='deferred' Return='asyncNoWait' Impersonate='no'/>
<InstallExecuteSequence>
<Custom Action='LaunchFile' Before='InstallFinalize'/>
</InstallExecuteSequence>
</Product>
I don't know why, but when I add:
<Directory Id='TARGETDIR' Name='SourceDir'>
<Component Id='MainExecutable' Guid='1193cd63-12d1-4792-829e-046de3bb987e'>
</Component>
</Directory>
<Feature Id='Complete' Level='1'>
<ComponentRef Id='MainExecutable' />
</Feature>
after Package node -> then it works fine. I need to figure out why...
I have some other concerns about what you are doing here, but if you really need to go out of process to an EXE to complete your install, then I'd suggest using the Quiet Execution Custom Action.
You should know though that this isn't a good practice for a number of reasons. 1) It's not declarative, 2) it doesn't support rollbacks. There are others but those are the biggest IMO.
BTW, WiX isn't "scripting". Understand that and you'll understand why not to call EXE's.
Because you are running the exe as a deferred action, it runs in the context of the SYSTEM account. This error is due to the system account not having the required permissions on the file system http://support.microsoft.com/kb/834484.
It is possible to get around this using PowerShell to execute the exe using the -RunAs switch, but this is a bit nasty. It really all depends exactly what you are doing in the exe as to the best course of action. I'm with Mr. Painter, using an EXE should be the last resort.
Another option is to move the exe setup code so that it runs the first time the user runs the app.
Important note for WIX, After completion of all application installation then the .sql file or database files runs through wix or wpf or winform application.

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>

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