Detect 64bit system from 32bit WIX installer - wix

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.

Related

Files not getting copied to install directory using WIX and WAX

I have some additional unmanaged dll's that need to be copied to the install folder. I am using WAX as well as it is supposed to make Wix easier to use. I have added the following markup to Product.wxs:
<Component Id="DataModel1.csdl" Guid="f8fb154d-f0c9-40f5-9bcf-593ed9540bda" Directory="INSTALLFOLDER">
<File Id="DataModel1.csdl" Name="DataModel1.csdl" Source="$(var.FLIR_TargetDir)DataModel1.csdl" />
</Component>
<Component Id="DataModel1.ssdl" Guid="a13c3c3b-e6a6-40ea-b9d8-84fd093ca0d5" Directory="INSTALLFOLDER">
<File Id="DataModel1.ssdl" Name="DataModel1.ssdl" Source="$(var.FLIR_TargetDir)DataModel1.ssdl" />
</Component>
<Component Id="DataModel1.msl" Guid="e308d75b-1f0b-4234-843d-6b44af2e80a9" Directory="INSTALLFOLDER">
<File Id="DataModel1.msl" Name="DataModel1.msl" Source="$(var.FLIR_TargetDir)" />
</Component>
<Component Id="Devart.Data.dll" Guid="a95a3053-7d4a-4030-b8c9-9d860a81a221" Directory="INSTALLFOLDER">
<File Id="Devart.Data.dll" Name="Devart.Data.dll" Assembly=".net" KeyPath="yes" Source="C:\Program Files (x86)\Devart\dotConnect\SQLite\Devart.Data.dll" />
</Component>
<Component Id="Devart.Data.SQLite.dll" Guid="16d0ca3c-425d-49e9-a754-043b0b9e4ada" Directory="INSTALLFOLDER">
<File Id="Devart.Data.SQLite.dll" Name="Devart.Data.SQLite.dll" Assembly=".net" KeyPath="yes" Source="C:\Program Files (x86)\Devart\dotConnect\SQLite\Devart.Data.SQLite.dll" />
</Component>
The files shows up as an unmapped file in the unmapped files area of the UI:
When the install happens the files do not get installed into the installation folder. What am I doing wrong?
The Assembly=".NET" tell's MSI to install the files in the Global Assembly Cache. The parent directory element is ignored/overridden. See:
http://wixtoolset.org/documentation/manual/v3/xsd/wix/file.html
If your looking for a tool to make WiX easier to learn/use then I'd suggest my own open source project:
https://github.com/iswix-llc/iswix-tutorials

Wix toolset Multiple Instances Installation

Some months ago I posted this question about multiple installation, and I strictly followed the example suggested me.
It worked very fine, but I try to remove the default Instance.
When I type
msiexec /x MyInstaller.msi
my App is "logically" removed, but no folders and no files are deleted on my machine!
Here is the code:
<Directory Id="TARGETDIR" Name="SourceDir">
<Component Id="comp_67F76B3C_8D92_4DCF_8C51_42E51502C4A3" Guid="28C71156-F612-49ED-A4E9-0CB598AA84AB" MultiInstance="yes">
<CreateFolder/>
</Component>
<Component Id="comp_AA102B27_0657_498D_9CD5_683C4F33B5E2" Guid="0F601C97-CDFF-4614-A608-B42253240E2C">
<File Id="_C72F9A1F_AF4A_47A3_928C_238643ABA5D4" Name="CrashReportManager.exe" Source="..\workspace\Release\CrashReportManager.exe" KeyPath="yes" />
</Component>
<Component Id="comp_442142FD_D0B8_410C_8904_E73047757FAB" Guid="0A1AE820-0FF7-442C-8333-9FEFA2E3F33C">
<File Id="_CA463C5C_E397_40E6_9B7B_28CCA647D0CA" Name="BCGCBPRO2440d120.dll" Source="..\workspace\Debug\BCGCBPRO2440d120.dll" KeyPath="yes" />
</Component>
<Directory Id="dir_350BD3EA_2F6C_4AD4_A960_8AB2C40F4F36" Name="Docs">
<Component Id="DocFolderId" Guid="32DAE480-7C01-4BAA-B99D-9FE8D7D43369" MultiInstance="yes">
<CreateFolder />
</Component>
<Component Id="comp_FFFDE3FE_1205_4E74_82B1_E832501A096C" Guid="EECC223C-EBAD-43CA-9F3C-4A19FD9E7429">
<File Id="_D0FE1868_D0D7_4778_8BC6_D40FE2B21DB2" Name="ModuleList(1).txt" Source="..\ModuleList(1).txt" KeyPath="yes" />
</Component>
<Component Id="comp_07E32598_CA8D_46B6_A3D6_DA36FD308E1F" Guid="FCCC41AA-17BC-4ADA-925D-631A614C9F80">
<File Id="_894CFDFB_4514_4CAC_86C3_426CC6836B7C" Name="ModuleList(2).txt" Source="..\ModuleList(2).txt" KeyPath="yes" />
</Component>
<Component Id="comp_21465088_A65C_43D4_A038_93412404BA91" Guid="67D18D29-6466-4D36-A279-A9396A62019C">
<File Id="_C9362477_88D8_463C_B77D_7097255F5E13" Name="ModuleList.txt" Source="..\ModuleList.txt" KeyPath="yes" />
</Component>
<Component Id="comp_3C85BB37_5715_45E7_A135_C640D7348360" Guid="6DDB0F88-7346-4221-8FB1-106C5F707EE5">
<File Id="_BFE55263_BD18_427B_9F87_30403BB2540D" Name="ReadMe.txt" Source="..\ReadMe.txt" KeyPath="yes" />
</Component>
</Directory>
</Directory>
What's wrong?
You used KeyPath="yes" in all of your components. This means, that such a component is used as a checkpoint for the Windows installer, for example if you want to repair an installation. It means that it is a mandatory component required for the application to function.
Since you are using multiple instances, and you mentioned you installed more than just the default instance, the Windows installer does not remove key components until the last one of the instances is getting uninstalled (i.e. it keeps track of them internally with a reference counter).
Use MultiInstance="yes" for each and every component, and like Yan says, get rid of the <CreateFolder/> component

Which would be the proper way to install one publisher policy in to the GAC using WIX?

Which would be the proper way to install one publisher policy in to the GAC using WIX 3.5?
I tried to do this:
<File
Id="LIBGAC"
Assembly=".net"
KeyPath="yes"
Vital="yes"
Name="ClassLibrary1.dll"
ProcessorArchitecture="msil"
DiskId="1"
Source="..\ClassLibrary1\bin\Release\ClassLibrary1.dll" >
</File>
</Component>
<Component Id="Config" Guid="F089B1AA-B593-4662-9DF4-F47EB9FBA1F4" >
<File
Id="LIBGACPolicy"
Assembly=".net"
KeyPath="yes"
Vital="yes"
Name="Policy.1.0.ClassLibrary1.dll"
DiskId="1"
Source="..\ClassLibrary1\policy.1.0.ClassLibrary1.dll" >
</File>
<File
Id="LIBGACPolicyConfig"
Source="..\ClassLibrary1\policy.1.0.ClassLibrary1.config"
CompanionFile="LIBGACPolicy">
</File>
</Component>
</Directory>
When compiling with VS2008 appears this error:
policy.1.0.ClassLibrary1.dll appears to be invalid. Please ensure this is a valid assembly file and that the user has the appropriate access rights to this file. More information: HRESULT: 0x8013101b
And lastly, when compiling with VS2010 doesn´t appear to be any problem. But
at finalizing the installation process, the DLL is well installed and the
publisher policy didn´t. Also I read the log generated during the installation and I wasn´t able to find a cause.
Thanks for reading.
I've been doing something similar and works well using Visual Studio 2010 and in a Build Server with MsBuild:
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="Gac" Name="Gac">
<!-- The component with the assembly -->
<Component Id="MiClassDLL" Guid="*">
<File Id="MiClass.dll" Assembly=".net" KeyPath="yes"
Source="$(var.MiClass.TargetPath)" />
</Component>
<!-- The component with the policy -->
<Component Id="PolicyMiClassDLL" Guid="{YOUR_GUID_HERE}">
<File Id="PolicyMiClass.dll" KeyPath="yes"
Source="$(var.MiClass.TargetDir)Policy.1.0.MiClass.dll" />
<File Id="PolicyMiClass.config" KeyPath="no"
Source="$(var.MiClass.ProjectDir)Policy.1.0.MiClass.config" />
</Component>
</Directory>
</Directory>
</Directory
In my case I have the policy.config file in the same project directory and I build the policy dll in the same output to make easier the installer script.
I noticed that the policy component must have a guid and for some reason it requires internally that policy dll and config files in the same directory/component.
I build the policy assembly in the Post-Build event of MiClass project with this command:
"C:\Program Files\Microsoft SDKs\Windows\v7.0A\bin\al.exe"
/link:"$(ProjectDir)Policy.1.0.MiClass.config"
/out:"$(TargetDir)Policy.1.0.MiClass.dll"
/keyfile:"$(SolutionDir)MyKeys.snk"
/comp:"My Company"
/prod:"My Product"
/productv:1.0
/version:1.0.0.0
I hope this works for you.
I did some work with policy dlls, and the only difference I can see is that your file naming convention is a little different than ours was.
Instead of
policy.1.0.ClassLibrary1.dll
policy.1.0.ClassLibrary1.config
We used
policy.1.0.ClassLibrary1.dll
ClassLibrary1.dll.config
instead of /link switch use /embed to compile the xml-config into publisher policy. then you can install the resulting assembly into GAC without problems

WiX - Install a driver which depends on the OS

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).

Redistributable failing in Vista

I am using the following code in my Wix Installer.
<DirectoryRef Id="TARGETDIR">
<Merge Id="CRT" Language="0" SourceFile=".\resources\Microsoft_VC90_CRT_x86.msm" DiskId="1" />
<Merge Id="ATL" Language="0" SourceFile=".\resources\Microsoft_VC90_ATL_x86.msm" DiskId="1" />
<Merge Id="MFC" Language="0" SourceFile=".\resources\Microsoft_VC90_MFC_x86.msm" DiskId="1" />
<Merge Id="MFCLOC" Language="0" SourceFile=".\resources\Microsoft_VC90_MFCLOC_x86.msm" DiskId="1" />
<Merge Id="OpenMP" Language="0" SourceFile=".\resources\Microsoft_VC90_OpenMP_x86.msm" DiskId="1" />
<Merge Id="CRT Policy" Language="0" src=".\resources\policy_9_0_Microsoft_VC90_CRT_x86.msm" DiskId="1" />
<Merge Id="MFC Policy" Language="0" src=".\resources\policy_9_0_Microsoft_VC90_MFC_x86.msm" DiskId="1" />
</DirectoryRef>
<Feature Id="VCRedist" Title="Visual C++ 9.0 Runtime" AllowAdvertise="no" Display="hidden" Level="1">
<MergeRef Id="CRT" />
<MergeRef Id="CRT Policy"/>
<MergeRef Id="ATL" />
<MergeRef Id="MFC" />
<MergeRef Id="MFC Policy"/>
<MergeRef Id="MFCLOC" />
<MergeRef Id="OpenMP" />
</Feature>
I feel that the msi build with this code works in many XP systems but fails in Vista. The programs and the shortcuts are getting created properly in Vista like XP.
What should I do in Vista to install these redistributables ?? I do not want to create a setup.exe with bootstrapper. My requirement states everything to be in a single msi only.
Any code example would help me a lot.
Thanks in advance for any valuable help.
Regards,
tvks
I thought that c++ redist is one of the packages recommended to be installed using the pre-packaged msi from MS. also i'm pretty sure all of the merge modules you included in your installer need corresponding policy merge modules not only crt and mfc.
another thing to check if your msi is elevating properly in Vista (UAC prompt)
In my current project we install the VC90 redistributables in the same way that you are describing in your post. We use the same attributes/values etc. However, we do not include any policy-modules. It works both under XP and Vista.
The Wix tutorial states that:
There is generally no need to include the policy MSMs as part of the installation.
So, if you have not given it a try, create an installation without any policies and see if that works better.