Create msi wrapper for InstallShield installer using WiX - wix

We've prepared installer for our client using InstallShield technology. Installer works fine but client wants this installer in msi technology. We decided to create wrapper using WiX. Msi installer should do few things:
Extract IS installer into temp directory.
Run InstallShield setup.exe.
Remove temporary directory after IS finish.
We haven't done installer in WiX technology before, those are our problems:
We don't know how to embed directory with all it's files (installer) into msi using WiX.
We don't know how to ONLY run msi (it shouldn't install data, only run embeded IS setup.exe during installation and remove after).
We don't know how to run exe during installation.
This is *.wxs file which I've created so far:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" Name="ISSetupPackeger" Language="1033" Version="1.0.0.0" Manufacturer="MyCompany" UpgradeCode="8804d459-2ea5-4bbc-85f7-dfc8419cafe4">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" Id="*" InstallPrivileges="elevated" />
<!-- TODO setup.exe starts but we don't want to run it using cmd -->
<CustomAction Id="LaunchInstaller" Directory="InstallerDir" ExeCommand="cmd /C setup.exe" Impersonate="yes" Return="ignore" />
<InstallExecuteSequence>
<Custom Action="LaunchInstaller" After="InstallFinalize" />
</InstallExecuteSequence>
<Media Id='1' Cabinet='data.cab' EmbedCab='yes'/>
<Feature Id="ProductFeature" Title="WixInstallerProject" Level="1">
<ComponentGroupRef Id="ProductComponents" />
</Feature>
<!-- TODO How to extract files to temp dir? Is there some TEMP constant? -->
<Directory Id="TARGETDIR" Name="SourceDir" >
<Directory Id="TempDir" Name="inst">
<Directory Id="InstallerDir" Name="Installer"/>
</Directory>
</Directory>
<!-- component group which will be installed into tempdir -->
<ComponentGroup Id="ProductComponents" Directory="InstallerDir">
<Component Id="Installer" Guid="7b8bd37f-7eda-4c3a-8155-9dae1a6bbf98">
<!-- TODO How to embed directory with all its files/subdirectories? -->
<File Id="_Setup.dll" Name="_Setup.dll" DiskId="1" Source="installer\_Setup.dll"/>
<File Id="data1.cab" Name="data1.cab" DiskId="1" Source="installer\data1.cab"/>
<File Id="data1.hdr" Name="data1.hdr" DiskId="1" Source="installer\data1.hdr"/>
<File Id="data2.cab" Name="data2.cab" DiskId="1" Source="installer\data2.cab"/>
<File Id="data2.hdr" Name="data2.hdr" DiskId="1" Source="installer\data2.hdr"/>
<File Id="ISSetup.dll" Name="ISSetup.dll" DiskId="1" Source="installer\ISSetup.dll"/>
<File Id="layout.bin" Name="layout.bin" DiskId="1" Source="installer\layout.bin"/>
<File Id="setup.exe" Name="setup.exe" DiskId="1" Source="installer\setup.exe"/>
<File Id="setup.ini" Name="setup.ini" DiskId="1" Source="installer\setup.ini"/>
</Component>
</ComponentGroup>
</Product>
</Wix>

Some alternatives:
From the files, it looks like the installer you have created with InstallShield is an InstallScript non-MSI installer. You might be able to convert it to an InstallScript MSI installer with an InstallShield converter. See this question and answer.
I read the requirement to convert to MSI differently than you do. For any kind of wrapping or converting to be worthwhile, it should take advantage of Windows Installer managing the installation of the files that are actually installed. To do that, you'd have to rewrite the installer from scratch if a conversion is not feasible. Your approach simply uses an MSI as a bundle. You should get clarification on what you want to do.
If you due go with the bundling route, WiX now offers a bootstrapper/downloader/chainer/bundler called Burn. With it, you can create a single .exe that will extract and run your existing installer. And, if you want, you can create an InstallShield response file so the existing install can be run silently. (See the InstallShield documentation for that.)

You can use a WiX Bootstrapper to embed your existing InstallShield executable. No conversion needed.
In our case the Setup.exe as built from InstallShield actually has an MSI inside. (I think this is usually the case). So then you have two options:
- you can either extract that MSI (google "extract MSI from InstallShield") and embedded it in the bootstapper using MsiPackage
- or you can embed the whole Setup.exe, using ExePackage
Passing Parameters to an MSI: easy
<MsiPackage Id="bla" SourceFile="path-to-msi>
<MsiProperty Name="PUBLIC_PROPERTY_IN_UPPERCASE" value="yourvalue"/>
</MsiPackage>
Passing parameters to an InstallShield Setup.exe: tricky
In our case Setup.exe ends up passing the parameters to the MSI anyway, use /v"the-parameters-go-here-but-you-have-to-escape-properly"
Sounds easy, but it was complicated to properly escape slashes (\), single-quotes ('), double quotes ("). Also, WiX escapes \ differently if the whole InstallArgument is enclosed in ' (single quotes) or " (double quotes). I started with single quotes because it looked easier, but ended up using double quotes. Use the install log to see what gets actually passed through each layer.
<Wix>
<Bundle>
<BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.HyperlinkLicense">
<bal:WixStandardBootstrapperApplication
xmlns:bal="http://schemas.microsoft.com/wix/BalExtension"
LicenseUrl=""/>
</BootstrapperApplicationRef>
<!-- rumor has it Windows Installer needs the trailing slash for paths -->
<Variable Name="InstallPath" Value="C:\path\to\destination\on\target\machine\" Type="string" bal:Overridable="yes"/>
<Chain>
<MsiPackage Id="package_your_msi"
SourceFile="path-to-msi"
DisplayInternalUI="no"
ForcePerMachine="yes"
Compressed="yes"
After="package_some_other_msi">
<MsiProperty Name="TEST_PROPERTY_5" Value="5"/>
</MsiPackage>
<ExePackage Id="package_installshield_setup_exe"
SourceFile="C:\path\to\Setup.exe"
Compressed="yes"
PerMachine="yes">
<CommandLine InstallArgument="/s /v"/qn INSTALLDIR=\"[InstallPath] \" HOST_ADDRESS=[HostAddress] HOST_PORT=[HostPort] SCANNER_MODEL=[ScannerType]""
Condition="use_registry_values=1 AND other_cond=1"/>
</ExePackage>
</Bundle>
</Wix>
Sources:
https://social.msdn.microsoft.com/Forums/windows/en-US/1a113abd-dca1-482b-ac91-ddb0dcc5465c/is-it-possible-to-pass-commandline-arguments-to-an-installshield-executable?forum=winformssetup
http://helpnet.installshield.com/installshield22helplib/helplibrary/IHelpSetup_EXECmdLine.htm

Related

Unable to uninstall program from WiX created MSI

After installing osquery with an MSI made with WiXToolSet (Using the script provided by osquery), I tried uninstalling it which failed.
Also it didn't show as a program in the appwiz.
(Link to the script - https://github.com/osquery/osquery/blob/master/tools/deployment/make_windows_package.ps1)
I've tried using both the MSI itself - osquery.msi /uninstall and the unsintall string - msiexec /I{'uninstallstring'}.
I also tried repairing using the /fv option.
The code the script used with WiX to create the MSI:
#'
<?xml version='1.0' encoding='windows-1252'?>
<?define OsqueryVersion = 'OSQUERY_VERSION'?>
<?define OsqueryUpgradeCode = 'ea6c7327-461e-4033-847c-acdf2b85dede'?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<Product
Name='osquery'
Manufacturer='Facebook'
'#
$wix += "`n Id='$(New-Guid)'`n"
$wix +=
#'
UpgradeCode='$(var.OsqueryUpgradeCode)'
Language='1033'
Codepage='1252'
Version='$(var.OsqueryVersion)'>
<Package Id='*'
Keywords='Installer'
Description='osquery standalone installer'
Comments='Facebooks opensource host intrusion detection agent'
Manufacturer='Facebook'
InstallerVersion='200'
Platform='x64'
Languages='1033'
Compressed='yes'
SummaryCodepage='1252' />
<MediaTemplate EmbedCab="yes" />
<MajorUpgrade
DowngradeErrorMessage="A later version of osquery is already installed. Setup will now exit." />
<Condition Message='A newer version of osquery is already installed.'>
NOT NEWERVERSIONDETECTED
</Condition>
<Condition Message="You need to be an administrator to install this product.">
Privileged
</Condition>
<Property Id='SOURCEDIRECTORY' Value='packs'/>
<PropertyRef Id="WIX_ACCOUNT_LOCALSYSTEM" />
<PropertyRef Id="WIX_ACCOUNT_USERS" />
<PropertyRef Id="WIX_ACCOUNT_ADMINISTRATORS" />
<Directory Id='TARGETDIR' Name='SourceDir'>
<Directory Id='ProgramFiles64Folder'>
<Directory Id='INSTALLFOLDER' Name='osquery'>
<Directory Id='DaemonFolder' Name='osqueryd'>
<Component Id='osqueryd'
Guid='41c9910d-bded-45dc-8f82-3cd00a24fa2f'>
<CreateFolder>
<Permission User="[WIX_ACCOUNT_USERS]" Read="yes"
ReadExtendedAttributes="yes" Traverse="yes"
ReadAttributes="yes" ReadPermission="yes" Synchronize="yes"
GenericWrite="no" WriteAttributes="no"/>
<Permission User="[WIX_ACCOUNT_ADMINISTRATORS]" GenericAll="yes"/>
<Permission User="[WIX_ACCOUNT_LOCALSYSTEM]" GenericAll="yes"/>
</CreateFolder>
<File Id='osqueryd'
Name='osqueryd.exe'
Source='OSQUERY_DAEMON_PATH'
KeyPath='yes'/>
<ServiceInstall Id='osqueryd'
Name='osqueryd'
Account='NT AUTHORITY\SYSTEM'
Arguments='--flagfile="C:\Program Files\osquery\osquery.flags"'
Start='auto'
Type='ownProcess'
Vital='yes'
ErrorControl='normal'/>
<ServiceControl Id='osqueryd'
Name='osqueryd'
Stop='both'
Start='install'
Remove='uninstall'
Wait='no'/>
</Component>
</Directory>
<Component Id='osqueryi' Guid='6a49524e-52b0-4e99-876f-ec50c0082a04'>
<File Id='osqueryi'
Name='osqueryi.exe'
Source='OSQUERY_SHELL_PATH'
KeyPath='yes'/>
</Component>
<Component Id='extras' Guid='3f435561-8fe7-4725-975a-95930c44d063'>
<File Id='osquery.conf'
Name='osquery.conf'
Source='OSQUERY_CONF_PATH'
KeyPath='yes'/>
<File Id='osquery.flags'
Name='osquery.flags'
Source='OSQUERY_FLAGS_PATH'/>
<File Id='osquery.man'
Name='osquery.man'
Source='OSQUERY_MAN_PATH'/>
<File Id='osquery_utils.ps1'
Name='osquery_utils.ps1'
Source='OSQUERY_UTILS_PATH'/>
<File Id='manage_osqueryd.ps1'
Name='manage-osqueryd.ps1'
Source='OSQUERY_MGMT_PATH'/>
'#
When trying to use the MSI to uninstall I saw the following message :
This patch package could not be opened. Verify that the patch package exists and that you can access it, or contact the application vendor to verify that this is a valid Windows Installer patch package
When trying to use the uninstall string I see this message:
This action is only valid for products that are currently installed
Upgrade Code Retrieval: How can I find the Upgrade Code for an
installed MSI file? (if you want to test the below with another package family, find upgrade code via methods described here).
Debugging: To find the product code (provided it is actually defined), maybe try to run this code:
Set installer = CreateObject("WindowsInstaller.Installer")
Set upgrades = installer.RelatedProducts("ea6c7327-461e-4033-847c-acdf2b85dede")
For Each u In upgrades
MsgBox u, vbOKOnly, "Product Code: "
Next
Procedure: 1) copy & paste the script into notepad, 2) save as ANSI file: "Find Related Products.vbs" on desktop, 3) double click script file to run. Make a note of the product codes shown by the message boxes (if any). Hit CTRL + C to copy content of the actual VBScript dialog.
Uninstall: From the cmd.exe using the product code you found by running the script above:
msiexec.exe /x {Product-Code}
Alternative: Browse through %SystemRoot%\Installer manually if you can't get the above to work, and follow the advice in section 4 here. Locate the right MSI, right click and go "Uninstall".
Links:
Powershell: Uninstall application by UpgradeCode

Wix create silent uninstall file

my idea is make an uninstall file with .msi install file. I read some information about creating uninstaller shortcut here: http://wixtoolset.org/documentation/manual/v3/howtos/files_and_registry/create_uninstall_shortcut.html , But i cant found information about make uninstall file after msi build , maybe whom know it's possible ? and if possible how i can do it ? or maybe it possible to do with cmd script? Just write script for automatically uninstall my program from mashine. My code is :
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension"><?define WpfApp1_TargetDir=$(var.WpfApp1.TargetDir)?>
<Product Id="*" Name="SetupProject2" Language="1033" Version="1.0.0.0" Manufacturer="Andrejka" UpgradeCode="PUT-GUID-HERE">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<Property Id="WIXUI_INSTALLDIR" Value="TESTFILEPRODUCTDIR" />
<Property Id="WixShellExecTarget" Value="[#WpfApp1.exe]" />
<CustomAction Id="LaunchApplication" BinaryKey="WixCA" DllEntry="WixShellExec" Impersonate="yes" />
<Property Id="LAUNCH_APP_ON_EXIT" Value="1" />
<InstallExecuteSequence>
<Custom Action='LaunchApplication' After='InstallFiles'/>
</InstallExecuteSequence>
<Property Id="WIXUI_EXITDIALOGOPTIONALCHECKBOX" Value="1" />
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate EmbedCab="yes"/>
<Feature Id="ProductFeature" Title="SetupProject2" Level="1">
<ComponentGroupRef Id="ProductComponents" />
</Feature>
</Product>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="TESTFILEPRODUCTDIR" Name="SetupProject2">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="SetupProject2" />
</Directory>
</Directory>
</Directory>
</Fragment>
<Fragment>
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
<!-- TODO: Remove the comments around this Component element and the ComponentRef below in order to add resources to this installer. -->
<!-- <Component Id="ProductComponent"> -->
<!-- TODO: Insert files, registry keys, and other resources here. -->
<!-- </Component> -->
<Component Id="WpfApp1.exe" Guid="*">
<File Id="WpfApp1.exe" Name="WpfApp1.exe" Source="$(var.WpfApp1_TargetDir)WpfApp1.exe" />
</Component>
<Component Id="WpfApp1.exe.config" Guid="*">
<File Id="WpfApp1.exe.config" Name="WpfApp1.exe.config" Source="$(var.WpfApp1_TargetDir)WpfApp1.exe.config" />
</Component>
<Component Id="aws_sdk_net_core_support.dll" Guid="*">
<File Id="aws_sdk_net_core_support.dll" Name="aws-sdk-net-core-support.dll" Source="$(var.WpfApp1_TargetDir)aws-sdk-net-core-support.dll" />
</Component>
<Component Id="AWSSDK.Core.dll" Guid="*">
<File Id="AWSSDK.Core.dll" Name="AWSSDK.Core.dll" Source="$(var.WpfApp1_TargetDir)AWSSDK.Core.dll" />
</Component>
<Component Id="AWSSDK.SimpleNotificationService.dll" Guid="*">
<File Id="AWSSDK.SimpleNotificationService.dll" Name="AWSSDK.SimpleNotificationService.dll" Source="$(var.WpfApp1_TargetDir)AWSSDK.SimpleNotificationService.dll" />
</Component>
<Component Id="MimeSharp.dll" Guid="*">
<File Id="MimeSharp.dll" Name="MimeSharp.dll" Source="$(var.WpfApp1_TargetDir)MimeSharp.dll" />
</Component>
</ComponentGroup>
</Fragment>
</Wix>
In general you are not supposed to put uninstall shortcuts in the start menu, it is in fact a violation of Microsoft's logo requirements for Windows applications I believe. Rather you should let people uninstall your product the normal way via the add/remove programs applet.
UPDATE: I found this answer with some more information on this topic: Shortcuts with name "Uninstall <Program Name>" are not displayed in Windows 8/8.1/10
Also, just so it is clear, uninstall, is a built-in feature of MSI files - it is always automatically available unless actively blocked (such as some applications hiding themselves from display in add/remove programs). There is nothing extra you have to do in your WiX sources to support uninstall properly. Just follow Windows Installer guidelines and it comes "for free".
If what you are asking is for a way to create an uninstall batch file, then you can find a plethora of ways to uninstall your MSI file in this "uninstall reference": Uninstalling an MSI file from the command line without using msiexec.
In short, just run the command line below to uninstall your MSI if you have the MSI's product code (you can find your product code by querying your system as described here: How can I find the product GUID of an installed MSI setup? - you might need to look it up since you auto-generate your product code):
msiexec.exe /x {your-product-guid}
or just uninstall by referring to your original MSI installation file like this:
msiexec.exe /x "c:\filename.msi
See the linked answer above (the uninstall reference) for a lot more information about this.

WIX Toolset - uninstalling .exe file

I wrote Wix Setup program, that wraps PyTangoArchiving-7.3.2.win-amd64.exe file into into PyTangoArchivingInstaller.msi package.
The installation procces is correct I think, in control pannel -> Programs I can see two additional programs installed:
PyTangoArchiving-7.3.2.win-amd64.exe - the program I wanted to install and
my wrapper - PyTangoArchivingInstaller.
But when I try to uninstall the application, only wrapper is being uninstalled and whole program (PyTangoArchiving-7.3.2.win-amd64.exe ) is still there, I have to uninstall it manually from Control Panel.
Can sb help me with this?
Here is my code:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" Name="PyTangoArchivingInstaller" Language="1033" Version="1.0.0.0" Manufacturer="test" UpgradeCode="PUT-GUID-HERE">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<WixVariable Id="WixUILicenseRtf" Value="$(var.ProjectDir)\License.rtf"/>
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLLOCATION"/>
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate EmbedCab="yes"/>
<UIRef Id="WixUI_InstallDir"/>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id='TempFolder'>
<Directory Id="INSTALLLOCATION" Name="MyApp" >
<Component Id='MyComponent' Guid='*'>
<File Id="mysetup_exe" Source="PyTangoArchiving-7.3.2.win-amd64.exe" />
</Component>
</Directory>
</Directory>
</Directory>
<Feature Id="MainApplication" Title="Main Application" Level="1">
<ComponentRef Id="MyComponent" />
</Feature>
<CustomAction Id="run_setup" FileKey="mysetup_exe" ExeCommand="/SP- /SILENT /SUPPRESSMSGBOXES /LANG=English
/NOCANCEL /DIR="[INSTALLLOCATION]""
Execute="deferred" Impersonate="no"
Return="check" />
<InstallExecuteSequence>
<Custom Action="run_setup" Sequence='5401'>NOT Installed</Custom>
</InstallExecuteSequence>
</Product>
</Wix>
As a general comment, you shouldn't usually be running another exe from inside your MSI, especially if it is an install that shows up in add/remove programs. You should instead use a bootstrapper to chain together multiple installs and this is the preferred way to do what you are trying to do.
Since you run your setup_exe from a custom action, you also need a corresponding custom action to uninstall it.
It would basically be the same format as the one you use to install except with the uninstall command line arguments, whatever they may be.
You will need to schedule your uninstall custom action before the "RemoveFiles" standard action so that the setup exe still exists when you try to run the custom action. You should also condition this custom action with REMOVE~="ALL" AND NOT UPGRADINGPRODUCTCODE.
This approach will run into problems when you try to support upgrades with/without upgrades to the packaged exe install. It is highly suggested you use either the wix burn bootstrapper (bit of a learning curve) or one of the other available bootstrappers for multiple install installations. These would more robustly and correctly support two installs along with upgrades and uninstalls.

WiX Bootstrapper

I am trying to create an installer for a simple .NET WPF C# app. I am using VS 2013, and WiX 3.10.2. Following the steps in the Wix Tutotial/ .NET/ Bootstrapping I have created a Boostrap.exe which chains .NET web installer and the app Setup.msi.
EDIT: My goal is to understand how to configure the WiX Bootstrap and Setup projects for small updates, minor upgrades, and major upgrades scenarios.
Out of the box, everything seems to work nice when I run a fresh install. However, when I run a fresh built Bootstrap.exe over an already existing installation a duplicate entry appears in the Apps & features and no file is changed in the app target location - contrary to the expectation that the same entry should remain in the Apps & features and the target location should be updated. EDIT: Looks like there may not be a way to change REINSTALLMODE?
If I add a Product Id and then change the version of the Setup (minor upgrade), the Bootstrap fails with User cancelled installation? The log file shows "Error 0x80070642: Failed to perform minor upgrade of MSI package." EDIT: Inside the MSI log a SecureRepair fails with error code 39439E438 (?) probably because the stored hash value does not match the current... but that should be expected in a minor upgrade MSI, right?
Are there recommended configurations between the Boostrapper and Setup WiX projects such that the small update, minor upgrade, and major upgrade use cases can be handled properly, or does the WiX Bootstrapper support ONLY major upgrades?
I will continue to investigate and I'll post updates to my findings;
Any hints are greatly appreciated,
Thanks!
Here are the source files which I barely changed from the WiX wizard generated code:
--- Product.wxs ---
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" Name="SetupProject1 1.0.0.0" Language="1033" Version="1.0.0.0" Manufacturer="Acme" UpgradeCode="4c8a8cbf-e3d0-410c-8a8d-7e67eb4e7ff7">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perUser" InstallPrivileges="limited" />
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate />
<Feature Id="ProductFeature" Title="SetupProject1" Level="1">
<ComponentGroupRef Id="ProductComponents" />
</Feature>
</Product>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="LocalAppDataFolder">
<Directory Id="AcmeFolder" Name="Acme">
<Directory Id="INSTALLFOLDER" Name="WpfApplication1" />
</Directory>
</Directory>
</Directory>
</Fragment>
<Fragment>
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
<Component Id="ProductComponent" Guid="8CA0B70F-39DA-4B4B-9104-46C58E26FCF4">
<CreateFolder/>
<RemoveFolder Id="RemoveAcmeFolder" Directory="AcmeFolder" On="uninstall"/>
<RemoveFolder Id="RemoveINSTALLFOLDER" On="uninstall" />
<RegistryValue Root="HKCU" Key="Software\Acme\WpfApplication1" Name="Version" Type="string" Value="[ProductVersion]" KeyPath="yes" />
<File Source="$(var.WpfApplication1.TargetPath)" KeyPath="no" />
</Component>
</ComponentGroup>
</Fragment>
--- Bundle.wxs ---
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:bal="http://schemas.microsoft.com/wix/BalExtension">
<Bundle Name="Bootstrapper1 1.0.0.0" Version="1.0.0.0" Manufacturer="Acme" UpgradeCode="e1092cbb-9134-42fc-a9f2-652f95f361fd">
<BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLicense" />
<Chain>
<MsiPackage Name="Acme Setup" SourceFile="$(var.SetupProject1.TargetPath)" Vital="yes" />
</Chain>
</Bundle>
If you change your executables, increase their version numbers. Windows Installer assumes files with the same versions are the same.
To upgrade an .msi package, increase its version number either as part of a major upgrade (typical) or minor upgrade.
To upgrade a bundle, increase its version number. By default, Burn keeps bundles with the same version installed.

Silent Installation of Application in a WiX Source File

I want to install microsoft visual c++ 2008 redistributable package along with my msi installer. I decide to include it along with my installer as an application file and i wrote a golang code that triggers the silent installation of microsoft visual c++ 2008 redistributable package. The Service of my application starts only when microsoft visual c++ 2008 redistributable package is installed. I could see a uninstall option for my application in the Control panel but i couldnt see anything like that for the microsoft visual c++ 2008 redistributable package. And i am pretty sure that the package is not installed because my application never starts, when i trigger the silent.exe (as an administrator) alone which has the code to silently install the package it gets installed and my application works fine as well. The problem occurs when i try to pack everything in a single msi.
The WiX Source file i wrote to include the silent.exe and also other necessary files i need for my application.
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:util='http://schemas.microsoft.com/wix/UtilExtension'>
<?include "CommonVariable.wxi"?>
<Product Id="*" Language="1033" Manufacturer="Testing" Name="Testing_Name" Version="1.1.1">
<Package InstallerVersion="111" Compressed="yes" Description = "(x64 Edition) MSI Package" Comments="(x64 Edition) MSI Package" InstallPrivileges="elevated" Platform="x64"/>
<Media Id="1" Cabinet="product.cab" EmbedCab="yes"/>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="MYINSTALLLOCATION" Name="$(var.foldername)">
<!-- Component for list of files to add in Installation location -->
<Component Id="ApplicationFiles" Guid="{**********-*******-*******-********}">
<File Id="ApplicationFile" Source="silent.exe" Vital="no" DiskId="1" Hidden="yes"/>
<File Id="ApplicationFile1" Source="Windows2008R2.exe" Vital="no" DiskId="1" Hidden="yes"/>
<File Id="ApplicationFile1" Source="Myfiles" Vital="no" DiskId="1" />
<File Id="ApplicationFile1" Source="Myfiles" Vital="no" DiskId="1" />
</Component>
***other Actions for my Application***
</Directory>
</Directory>
</Directory>
<DirectoryRef Id="MYINSTALLLOCATION">
<Component Id="CleanupMainApplicationFolder" Guid="{**********-*******-*******-********}" Win64="yes">
<util:RemoveFolderEx On="uninstall" Property="MYINSTALLLOCATION" />
</Component>
</DirectoryRef>
<Property Id="MYINSTALLLOCATION" Value="$(var.InstallationLocation)" >
</Property>
<Feature Id="DefaultFeature" Level="1">
<ComponentRef Id="ApplicationFiles"/>
</Feature>
<Binary Id="ExeId" SourceFile="silent.exe"/>
<CustomAction Id="SilentAction" BinaryKey="ExeId" ExeCommand="" Execute='deferred' Return ='asyncWait' Impersonate='no'/>
<InstallExecuteSequence>
<Custom Action='SilentAction' Before='InstallFinalize'/>
</InstallExecuteSequence>
</Product>
</Wix>
The Silent.exe is the golang code i wrote has many functions the part of the code i wrote to silently install the package is as below.
package main
import (
"fmt"
"os/exec"
)
func main() {
/*........................
...........................
..........................*/
/*The code above is for my Different purpose */
co := exec.Command("C:\\Windows2008R2.exe","/q","/c:\"msiexec","/i","Windows2008R2.msi","/qn","/l*v","C:\\Windows2008R2_x64.log\"")
if err := co.Run(); err != nil {
fmt.Println("Error: ", err)
}
}
Windows does not allow you to install an application when another application is being installed.So better you can have a MSI for that redistributable package and invoke it separately after the previous installation is done through wmic remote command.