WiX - Install a driver which depends on the OS - wix

During the installation, I have to install an external driver which depends on the operating system of the PC. I know I can build several installer packages for every OS, but I have to do it in one installer. Is that possible?
My first problem is to find out which operating system exists on the PC. Via a condition like the following?
<Condition Message="Your Operating system is ... .">
VersionNT = 500
<?define PCPlatform = "Win2000" ?>
OR VersionNT = 501
<?define PCPlatform = "XP" ?>
OR VersionNT = 600
<?define PCPlatform = "Vista" ?>
OR VersionNT = 601
<?define PCPlatform = "Win7" ?>
</Condition>
And then how to tell the installer which file is to execute?
<Component Id="Win32_W2K" Guid="...">
<File Id="vbsetup7" Source="..\driver\32Bit\W2K\vbsetup7.exe" Name="vbsetup7.exe" KeyPath="yes" DiskId="1"/>
</Component>
<Component Id="Win32_XP" Guid="...">
<File Id="vbsetup7" Source="..\driver\32Bit\XP\vbsetup7.exe" Name="vbsetup7.exe" KeyPath="yes" DiskId="1"/>
</Component>
<Component Id="Win32_Vista" Guid="...">
<File Id="vbsetup7" Source="..\driver\32Bit\Vista\vbsetup7.exe" Name="vbsetup7.exe" KeyPath="yes" DiskId="1"/>
</Component>
<Component Id="Win32_Win7" Guid="...">
<File Id="vbsetup7" Source="..\driver\32Bit\Win7\vbsetup7.exe" Name="vbsetup7.exe" KeyPath="yes" DiskId="1"/>
</Component>
<CustomAction Id="Virtual_Driver" FileKey="vbsetup7" Execute="deferred" ExeCommand="" Return="check" Impersonate="no"/>

You have to add Condition to your components. At runtime, Condition must evaluate to true for only one of the component elements, that is, conditions must be mutually exclusive. Something like:
<Component Id="Win32_W2K" Guid="...">
<Condition>VersionNT = 500</Condition>
<File Id="vbsetup7" Source="..\driver\32Bit\W2K\vbsetup7.exe" Name="vbsetup7.exe" KeyPath="yes" DiskId="1"/>
</Component>

How are you installing the drivers? If you are using DifxApp then you will have to have more than one installer, one for each target architecture (x86 vs x64). There are wixlibs for Difxapp that make driver installation pretty easy.

You may have problems if you have to run one installer "inside" another, especially if the second package is also Windows Installer-based, because Windows Installer (MSI) does not support "nested" installs. Some of the resources that MSI works with are effectively global, so the inner installation can tromp on the outer-install-in-progress.
A better approach is to use a chain of installs. In WiX, these are called bundles, and are run by the burn bootstrapper. You can apply conditions to each element of the bundle, so that a given element is run only for a certain Windows version (or service-pack level, or x86|x64, or if some other package is or is not present on the system, or... Install conditions can be as flexible as you like).

Related

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.

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

Detect 64bit system from 32bit WIX installer

I have a 32bit WIX installer that installs a .NET based windows service. I need to use one external .dll that comes in 32bit and 64bit versions. Is there any way a 32bit installer can detect it's running on a 64bit machine? I want to then conditionally install the 32 or 64 bit .dll.
Extending Morten's answer, I did this in Wix 3.6
<Component Directory="INSTALLLOCATION">
<File Id="msvcp100.dll_x64" Source="$(var.x64)\msvcp100.dll" KeyPath="yes" />
<Condition><![CDATA[VersionNT64]]></Condition>
</Component>
<Component Directory="INSTALLLOCATION">
<File Id="msvcp100.dll_x86" Source="$(var.x86)\msvcp100.dll" KeyPath="yes" />
<Condition><![CDATA[Not VersionNT64]]></Condition>
</Component>
Try this:
<Component Id="Component1" Guid="*">
<![CDATA[Not VersionNT64]]>
<File Id="File1" Name="1.dll" Source="c:\dlls\1.dll"/>
</Component>
<Component Id="Component2" Guid="*">
<![CDATA[VersionNT64]]>
<File Id="File2" Name="2.dll" Source="c:\dlls\2.dll"/>
</Component>
Create a property with ProcessorArchitecture and get the value of this from registry. Based on this property create a CONDITIONAL FEATURE.

Wix major upgrade; need different behaviors for different components [duplicate]

This question already has an answer here:
WiX custom action with DTF... quite confused
(1 answer)
Closed 2 years ago.
Okay! I have finally more closely identified the problem I'm having. In my installer, I was attempting to get a settings file to remain intact on a major upgrade. I finally got this to work with the suggestion to set
<InstallExecuteSequence>
<RemoveExistingProducts After="InstallFinalize" />
</InstallExecuteSequence>
This is successful in forcing this component to leave the original, not replacing it if it exists:
<Component Id="Settings" Guid="A3513208-4F12-4496-B609-197812B4A953" NeverOverwrite="yes">
<File Id="settingsXml" KeyPath="yes" ShortName="SETTINGS.XML" Name="Settings.xml" DiskId="1" Source="\\fileserver\Release\Pathways\Dependencies\Settings\settings.xml" Vital="yes" />
</Component>
However, this is a problem. I have another component listed here:
<Component Id="Database" Guid="1D8756EF-FD6C-49BC-8400-299492E8C65D" KeyPath="yes">
<File Id="pathwaysMdf" Name="Pathways.mdf" DiskId="1" Source="\\fileserver\Shared\Databases\Pathways\SystemDBs\Pathways.mdf" Vital="yes"/>
<File Id="pathwaysLdf" Name="Pathways_log.ldf" DiskId="1" Source="\\fileserver\Shared\Databases\Pathways\SystemDBs\Pathways.ldf" Vital="yes"/>
</Component>
And this component must be replaced on a major upgrade. I can only accomplish this so far by setting
<RemoveExistingProducts After="InstallInitialize" />
This breaks the first functionality I need with the settings file. How can I do both?
The problem is that settings.xml shouldn't be installed in the first place, what you really want to do is install something like a 'defaultSettings.xml' and have user-editable settings in a separate location, copying the default to the user/system config in either a post-install configuration step or at first run. If the user modifies the file, and runs a "repair" then it's going to get overwritten anyway, this is the intended behavior of Windows Installer.
If you really want Windows Installer to "leave the file alone" then you're going to need an unmanaged component, i.e. a component with an empty GUID. Such as...
<Component Id="Settings" Guid="" NeverOverwrite="yes">
<File Id="settingsXml" KeyPath="yes" ShortName="SETTINGS.XML" Name="Settings.xml" DiskId="1" Source="\\fileserver\Release\Pathways\Dependencies\Settings\settings.xml" Vital="yes" />
</Component>

Generating an executable using wix

I am learning Wix and I want to generate a setup.exe file instead of a setup.msi.
Is that possible?
A setup EXE is usually referred to as a bootstrapper or chainer. WiX 3.5 will ship with an executable called burn.exe, unfortunately this is still under heavy development.
If you're just after a basic self-extracting EXE with no additional logic you can use the included setupbld.exe with WiX. However it's pretty limited and only includes the most basic functionality.
Alternatively, 7-zip includes basic functionality for creating a setup.exe from an existing MSI. You will need to install the SFXs for installers addon first.
If you're after additional logic, dependency checking, etc. there are loads of alternatives. Personally I use IRMakeBootstrap, but have heard very good things about dotNetInstaller on the wix-users mailing list.
dotNetInstaller
IRMakeBootstrap (Commercial product, licensed as part of MSI Factory)
Visual Studio Bootstrapper (Supports dependencies, not sure about self-extracting exe though)
step 1.Create window application
step 2. Add setp project
step 3. Add reference
1.WixNetFxExtension.dll
2.WixNetFxExtension.dll
3.WixNetFxExtension.dll
step 4. Add folowing code
<Component Id="ProductComponent">
<File Id="installation"
source="E:\MyWork\WindowsFormsApplication2\
WindowsFormsApplication2\bin\Debug/
WindowsFormsApplication2.exe"/>
<!-- TODO: Insert files, registry keys, and other
resources here. -->
</Component>
step 5. <Property Id="WIXUI_INSTALLDIR"
Value="INSTALLFOLDER" ></Property>
<UIRef Id="WixUI_InstallDir"/>
step 6.
<Directory Id="DesktopFolder" Name="Desktop"/>
<Directory Id="INSTALLFOLDER" Name="SetupProject1"
/>
step 7. <ComponentRef
Id="ApplicationShortcutDesktop"/>
step 8.<Fragment>
<DirectoryRef Id="DesktopFolder">
<Component Id="ApplicationShortcutDesktop"
Guid="cde1e030-eb64-49a5-b7b8-400b379c2d1a">
<Shortcut Id="ApplicationDesktopShortcut"
Name="SetupProject1" Description="SetupProject1"
Target=".
[INSTALLFOLDER]WindowsFormsApplication2.exe"
WorkingDirectory="INSTALLFOLDER" />
<RemoveFolder Id="RemoveDesktopFolder"
Directory="DesktopFolder" On="uninstall" />
<RegistryValue Root="HKCU"
Key="Software\SetupProject1" Name="installed"
Type="integer" Value="1" KeyPath="yes" />
</Component>
</DirectoryRef>
</Fragment>
step 9.build and install setup