Unable to uninstall program from WiX created MSI - wix

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

Related

Issues with uninstall program in control panel built with WiX toolset

I'm creating msi installer that run services with auto start for windows using wix toolset. msi was successfully compiled and installed, and services are working correctly.
The problem is that, when i try to uninstall the program in control panel, it's showing the following message:
I tried to remove the program from regedit and tried to install using the command:
MsiExec /I installer.msi REINSTALLMODE=voums REINSTALL=ALL
Here is the code of product and package declarations:
<Product Name='Foobar 1.0' Manufacturer='Acme Ltd.' Id='6DA5C23A-86C7-4D14-AEC0-86416A69ABDE' UpgradeCode='6DA5C23A-7349-453F-94F6-BCB5110BA4FD' Language='1033' Codepage='1252' Version='1.0.0'>
<Package Id='*' Keywords='Installer' Description="Acme's Foobar 1.0 Installer" Comments='Foobar is a registered trademark of Acme Ltd.' Manufacturer='Acme Ltd.' InstallerVersion='100' Languages='1033' Compressed='yes' SummaryCodepage='1252' />
In INSTALLDIR, i have an exe file for service, and do some actions:
<Directory Id='INSTALLDIR' Name='Foobar 1.0'>
<Component Id='ConfPathEnv' Guid='6DA5C23A-6BE3-460D-A14F-75658D16550B' KeyPath="yes">
<Environment Id="AQLIGHT_CONFIG_PATH" Name="AQLIGHT_CONFIG_PATH" Value="[INSTALLDIR]config.json" Permanent="yes" Part="last" Action="set" System="yes" />
</Component>
<Component Id='MainExecutable' Guid='6DA5C23A-83F1-4F22-985B-FDB3C8ABD471'>
<File Id='serviceEXE' Name='service.exe' DiskId='1' Source='service.exe' KeyPath='yes' />
<ServiceInstall Id="InstallService" Name="AqLightService" DisplayName="AqLightService 1.0" Start="auto" ErrorControl="normal" Arguments="install" Type="ownProcess" />
<ServiceControl Id="ControlService" Name="AqLightService" Start="install" Stop="uninstall" Remove="uninstall" Wait="yes" />
</Component>
</Directory>
In order to remove folder when uninstalling the program, i use the following code:
<Directory Id="ProgramMenuFolder" Name="Programs">
<Directory Id="ProgramMenuDir" Name="Foobar 1.0">
<Component Id="ProgramMenuDir" Guid="6DA5C23A-7E98-44CE-B049-C477CC0A2B00">
<RemoveFolder Id='ProgramMenuDir' On='uninstall' />
<RegistryValue Root='HKCU' Key='Software\[Manufacturer]\[ProductName]' Type='string' Value='' KeyPath='yes' />
</Component>
</Directory>
</Directory>
I tried to change the GUIDs for each componet several times, but it did't help.
Custom Action: That error message can mean a number of things, but most commonly it is caused by a failing custom action. However, in this case it looks like the message is from iTunes?
Logging: No two ways about it: you need a verbose log file to try and make sense of this (adjust paths as appropriate):
msiexec.exe /x "Setup.msi" /L*V "C:\Setup.log"
Self-Repair?: My guess is that you have a corrupted machine / Windows Installer Database, or a self-repair problem that you have
turned into a corrupt machine by hacking the registry. Maybe. On Self-Repair.
Conditioning: When you need conditions to run only at certain times / installation modes - you need to deal with conditioning. There are many previous answers on MSI conditions. They are always hard to get right and testing is essential. Please see the answers below for information:
"MSI Condition Cheat Sheet"
Wix custom uninstallation action - how to run before msi removing files
How to execute conditional custom action on install and modify only? - tip on how to test conditions using VBScript and the MSI API call "EvaluateCondition" at runtime - ze proof izt in ze pudding! :-).
This condition might be enough for you (no guarantees):
NOT Installed AND NOT UPGRADINGPRODUCTCODE
Please test in all installation modes: : install, uninstall, modify, repair, self-repair, patching, major upgrade, etc.... Hard to tell how things can conspire, no substitute for real-world testing (just to state the obvious).
Here are more details on logging and interpreting the log file:
Installsite.org on logging
Interpreting MSI log files, etc...
Event logging, etc...
And another answer on logging.

WiX retrieve path from registry confusion

I am trying to create a WiX installer for a plugin of one of my applications but have come across something I find strange; perhaps it is the expected behavior but then I would like to know why.
My application saves its installation path in the following registry location:
HKEY_CURRENT_USER\SOFTWARE\MyCompany\MyApp\Installed
As default my application is installed to C:\Program Files\MyApp if x64 and C:\Program Files (x86)\MyApp if x86.
In my plugin installer I have the following in Product.wxs to retrieve the install path of my application:
<Property Id="MY_APP_DIR">
<RegistrySearch Id='my_app_dir' Type='raw' Root='HKCU' Key='SOFTWARE\MyCompany\MyApp' Name='Installed' />
</Property>
I then added the following just to see what is actually retrieved when I run the installer:
<Condition Message="[MY_APP_DIR]">
0
</Condition>
In the case where "C:\Program Files\MyApp\" is stored in the registry I got the following when I run the plugin installer:
Plugin installer (x86): C:\Program Files (x86)\MyApp\
Plugin installer (x64): C:\Program Files\MyApp\
Why is not the value stored in the registry retrieved independently of which platform the msi was built for?
On a x64 machine only the x64 versions of my installers will be used so this should not cause any problems it just confuses me.
EDIT: As requested I have included my entire Product.wxs:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" Name="TestInstaller" Language="1033" Version="1.0.0.0" Manufacturer="MyCompany" UpgradeCode="SOME_GUID">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate EmbedCab="yes" />
<Property Id="MY_APP_DIR">
<RegistrySearch Id="my_app_dir" Root="HKCU" Key="SOFTWARE\MyCompany\MyApp" Name="Installed" Type="raw" />
</Property>
<Condition Message="[MY_APP_DIR]">
0
</Condition>
<Feature Id="ProductFeature" Title="TestInstaller" Level="1">
<ComponentGroupRef Id="ProductComponents" />
</Feature>
</Product>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="INSTALLFOLDER" Name="TestInstaller">
<Directory Id="MY_APP_DIR" Name="MyAppInstallPath">
<Directory Id="MyAppBinFolder" Name="bin" />
</Directory>
</Directory>
</Directory>
</Fragment>
<Fragment>
<ComponentGroup Id="ProductComponents">
<Component Id="ProductComponent" Guid="SOME_GUID" Directory="MyAppBinFolder">
<File Id="Foo.Bar" Source="Foo.Bar" KeyPath="yes" />
</Component>
</ComponentGroup>
</Fragment>
</Wix>
Windows Installer has a rule called WIN64DUALFOLDERS which does not allow 32 bit installers to write to 64 bit locations. If you run your 32 bit installer on a 64 bit computer with diagnostic logging enabled you should see a section in the log file like this:
AppSearch: Property: MY_APP_DIR, Signature: my_app_dir
MSI (c) (BC:F4) [10:00:47:953]: Note: 1: 2262 2: Signature 3: -2147287038
MSI (c) (BC:F4) [10:00:47:953]: WIN64DUALFOLDERS: 'C:\Program Files (x86)\' will substitute 17 characters in 'C:\Program Files\MyCompany\MyApp' folder path. (mask argument = 0, the folder pair's iSwapAttrib member = 0).
MSI (c) (BC:F4) [10:00:47:953]: PROPERTY CHANGE: Adding MY_APP_DIR property. Its value is 'C:\Program Files (x86)\MyCompany\MyApp'.
Action ended 10:00:47: AppSearch. Return value 1.
Even though the path in the registry is C:\Program Files\, Windows Installer automatically redirects it to C:\Program Files (x86)\.
For more information see Disable WIN64DUALFOLDERS substitution in WIX.
Note: I deleted my previous answer because with the benefit of hindsight it wasn't useful.

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.

Wix SqlDatabase creation of 2014 LocalDb Error

I have a Wix Toolset project that needs to install a database into an existing install of SqlServer 2014 LocalDb and I've not been successful at all. I've searched extensively on SO as well as other sites for examples or suggestions that might be applicable. So far, I've found nothing that works in my project.
SqlServer Local DB was already installed on the system and can be access from SQL Mgmt Studio. All of the system databases appear as expected and I'm able to create a new database in Mgmt Studio.
The text file that I include as a test does install correctly in the expected folder.
The error that I am receiving varies depending on which options I define within the SqlDatabase element.
From the installer log:
Action 11:46:34: CreateFolders. Creating folders
CreateFolders: Folder: C:\Check\Database\
CreateFolders: Folder: C:\Check\Database\
Action 11:46:34: InstallFiles. Copying new files
InstallFiles: File: TestFile.txt, Directory: C:\Check\Database\, Size: 19
Action 11:46:34: CreateDatabase. Creating Databases
CreateDatabase: Error 0x80004005: failed to create SQL database but continuing error: unknown error, Database: Check
Action 11:46:51: RegisterProduct. Registering product
The wxs file for this installation:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:util='http://schemas.microsoft.com/wix/UtilExtension'
xmlns:sql='http://schemas.microsoft.com/wix/SqlExtension'>
<Product Id="*" Name="Ach Check Database Installation" Language="1033" Version="1.0.0.0" Manufacturer="ACH Solutions" UpgradeCode="3828eaf7-528f-4006-9169-27bed44e79fe">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate EmbedCab="yes"/>
<Feature Id="CheckDb" Title="Check Database" Description="The Check Database" ConfigurableDirectory="INSTALLDIR" Level="1">
<ComponentGroupRef Id="DatabaseComponents" />
</Feature>
<UIRef Id="WixUI_Mondo" />
</Product>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="INSTALLDIR" Name="CheckDir" >
<Directory Id="DatabaseFolder" Name="Database" />
</Directory>
</Directory>
</Fragment>
<Fragment>
<ComponentGroup Id="DatabaseComponents" Directory="DatabaseFolder">
<Component Id='SqlComponent' Guid='53234257-65F1-4D58-B2CA-90308EC102FF'>
<CreateFolder />
<File Id="file_TestFile.txt" Source="E:\TestFile.txt"/>
</Component>
<Component Id="sql_SqlDatabase" Guid="B4D9CB63-B740-4860-89B6-1209D9A1A18E">
<CreateFolder/>
<sql:SqlDatabase Id='SqlDatabase'
Database='Check'
CreateOnInstall='yes'
Server='localhost\(localdb)\MsSqlLocalDb'
DropOnUninstall='no'
ContinueOnError='yes'>
<sql:SqlFileSpec Id='sql_CheckDatabase' Filename='CheckDatabase.mdb' Name='CheckDatabase' Size='30MB' />
<sql:SqlLogFileSpec Id='sql_CheckDatabase_Log' Filename='CheckDatabase_Log.ldb' Name='CheckDatabaseLog' Size='3MB' />
</sql:SqlDatabase>
</Component>
</ComponentGroup>
</Fragment>
</Wix>
Has anyone run into this problem or something similar before? What was the solution?
I welcome any suggestions that might assist in this.
Thanks,
Eugene
I believe the Server attribute should be just '(localdb)\MsSqlLocalDb'.
Also make sure the LocalDB instance exists by the time you run the installer and that it's shared with the user under which the installer is running.
For testing purposes you can also try to use named pipe instead of server name. To get the name of the instance's pipe run the following command in the command line:
sqllocaldb info MsSqlLocalDb
WiX doesn't support localdb connections.
https://github.com/wixtoolset/issues/issues/4957
https://social.msdn.microsoft.com/Forums/sqlserver/en-US/b5c9a1fa-75fc-41f2-a5d3-4b2b6ed4ebde/localdb-problem-unable-to-connection-via-localdbv110-but-can-via-named-paipes
Someone would have to update dutil to use the latest SQL Server Native Client and it seems in 7 years no one has.
The alternative is to write your own custom actions for SQL processing. I have some that I can provide if you email me a request.

Create msi wrapper for InstallShield installer using 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