Sequencing Components in Feature Element - wix

I want to replace a file that has been installed by my installer. In the following code the "OneCoreFiles" component should install the files first time( which is working) and the component "ConfigCopyFile" should replace that config file.
But the code is not working as expected. The component 'ConfigCopyFile' is getting executed first and then the 'OnecoreFiles'. I want it to work the other way.
I am still learning WIX and thought that the components in Feature elements are executed in the order in which they are declared.
Code Snippet:
<Component Id="ConfigCopyFile" Guid="{98E61055-5A84-4003-90D1-7A67677D7465}">
<Condition>CONFIGFILEEXISTS</Condition>
<CopyFile Id="ConfigFileId" SourceProperty="CONFIGFILEEXISTS" DestinationProperty ="INSTALLDIR"/>
</Component>
<Feature Id="ProductFeature" Title="OneCore Features" Level="1">
<ComponentRef Id="LogEntries" />
<ComponentGroupRef Id="OneCoreFiles" />
<ComponentRef Id="AppDBConfiguration" />
<ComponentRef Id="SqlServerConfiguration" />
<ComponentRef Id="OracleConfiguration" />
<ComponentRef Id="IISConfiguration" />
<ComponentRef Id="ConfigCopyFile" />
</Feature>
This must be quite simple to solve. Am I missing something. Please advice.

You are thinking of WiX in the wrong way. It's not a scripting language. It's a way of representing Windows Installer databases which are declarative in nature not imperative. If I list a bunch of components and files it's non deterministic the order the files will be copied. I'm only saying that these files need to be installed not how to install them.
Windows Installer does expose sequence tables which drive the order of things ( such as create folders then copy files ) but it doesn't micromanage to the level of copy this file before that file.
Suggested InstallExecute Sequence
InstallExecuteSequence Table

Related

WiX and Merge Modules - to include, or not, the policy files?

I am including the VS 2005 merge modules into an MSI. The code is in place and the MSI builds.
<Fragment>
<DirectoryRef Id="TARGETDIR">
<!--
WiX docs say "There is generally no need to include the policy MSMs as part of the installation.", but, the former Installshield
project did include it, so, including here now. Remove it if it's actually not required.
http://wixtoolset.org/documentation/manual/v3/howtos/redistributables_and_install_checks/install_vcredist.html
-->
<Merge Id="VCRedist2005_32" SourceFile="$(var.RESOURCES)\MergeModules\VS2005\Microsoft_VC80_CRT_x86.msm" DiskId="1" Language="0"/>
<Merge Id="VCRedist2005_64" SourceFile="$(var.RESOURCES)\MergeModules\VS2005\Microsoft_VC80_CRT_x86_x64.msm" DiskId="1" Language="0"/>
<!--
<Merge Id="VCRedistPolicy2005_32" SourceFile="$(var.RESOURCES)\MergeModules\VS2005\policy_8_0_Microsoft_VC80_CRT_x86.msm" DiskId="1" Language="0"/>
<Merge Id="VCRedistPolicy2005_64" SourceFile="$(var.RESOURCES)\MergeModules\VS2005\policy_8_0_Microsoft_VC80_CRT_x86_x64.msm" DiskId="1" Language="0"/>
-->
</DirectoryRef>
</Fragment>
And in my Product.wxs:
<Feature ...>
<ComponentRef Id="Client_Registry" />
<?if $(var.Product) = xx ?>
<MergeRef Id="VCRedist2005_32"/>
<MergeRef Id="VCRedist2005_64"/>
<!--
<MergeRef Id="VCRedistPolicy2005_32"/>
<MergeRef Id="VCRedistPolicy2005_64"/>
-->
<?endif?>
</Feature>
I am concerned about two warnings though:
1>light.exe(0,0): warning LGHT1076: ICE25: Possible dependency failure as we do not find CRT.Policy.63E949F6_03BC_5C40_FF1F_C8B3B9A1E18E#0 v in ModuleSignature table
1>light.exe(0,0): warning LGHT1076: ICE25: Possible dependency failure as we do not find CRT.Policy.4F6D20F0_CCE5_1492_FF1F_C8B3B9A1E18E#0 v in ModuleSignature table
Two messages because I am including both the 32 and 64-bit merge modules.
I did not add the policy files because the wix page suggests not to. A MS blog page also backs that up. But, then there are pages such as this one, where the advice is TO include them.
So, I am unsure how to proceed. Should the policy files be included or not? And if not, why not?
I've always preferred to bootstrap the vcredist runtime instead. Keeps my MSI all nice and clean with no issues.

Install merge module for all users using WiX

I created an Installer using WiX to install a VSIX along with two dependent components. These two components were available to me in the form of Merge Modules. Below is the code where I used the merge modules in my code:
<DirectoryRef Id="TARGETDIR">
<Merge Id="MergeModuleID1" SourceFile="MergeModule1.msm" DiskId="1" Language="0"/>
<Merge Id="MergeModuleID2" SourceFile="MergeModule2.msm" DiskId="1" Language="0" />
</DirectoryRef>
and I've referred these merge modules as:
<Feature Id="ProductFeature" Title="Title" Level="1">
<ComponentRef Id="VSPackage"/>
<ComponentRef Id="ApplicationShortcut"/>
<ComponentRef Id="DesktopShortcut"/>
<ComponentRef Id="LicenseComp"/>
<MergeRef Id="MergeModuleID1"/>
<MergeRef Id="MergeModuleID2"/>
</Feature>
The problem I'm facing is, that my VSIX is installed to all the user accounts on the machine, but these merge modules are not, they're installed only on the user account where the product is installed. On other user accounts, an installation dialog appears, which I believe is installing these merge modules, after which everything works fine.
How do I make these merge modules to be installed to all users?
P.S: ALLUSERS property in both the MSI and merge modules are set to '1'.
You may need to clarify that question somewhat. Merge modules are not installed, just the files, so you mean the files in merge modules are going somewhere incorrect, yes? Also, files are not installed on a user account they got to a location on disk.
Guessing my way through this, you're probably saying that the files get installed to somewhere like the User's Application Data location for the installing user. If that's what the merge modules specify in their internals, that's normal. You can obviously install files to the current user's application data folder even if you're doing a per machine install. I can't say if those merge modules are correctly designed or not, but if they are then:
The initial install will put those files in the installing users file location.
If another logs on and uses a shortcut and your MSI is correctly designed, the install-on-demand feature will install those files for that user in that user's folder, maybe asking for the original install media. That's the way this is designed to work because:
a) There is no mechanism that that allows a file to be installed simultaneously to all user file locations on the system, and it makes no sense anyway if they never use the app.
b) What happens if you create a new user account AFTER the product has been installed? The file will not be in that user's location, however the install on demand scheme guarantees that this new user will get the file in their location if they log on and use the app.
The short answer is that this is probably all working as intended.
Setting ALLUSERS is fine.
What you've described looks like "advertising".
To remove advertising for the Merge Modules, add AllowAdvertise="no" to the Attributes of the Feature containing the MergeRef element :
<Feature Id="ProductFeature" Title="Title" AllowAdvertise="no" Level="1">
<ComponentRef Id="VSPackage"/>
<ComponentRef Id="ApplicationShortcut"/>
<ComponentRef Id="DesktopShortcut"/>
<ComponentRef Id="LicenseComp"/>
<MergeRef Id="MergeModuleID1"/>
<MergeRef Id="MergeModuleID2"/>
</Feature>

Installing multiple components with single msi

I have a software that assembled with about 19 different components. Right now I use 19 setup projects and 1 Winforms project that is the main installer. I want to move to WiX since I want to upgrade to visual studio 2012. My question is: is it possible to do that in WiX? In current setup I have, user able to decide which components to install by checking them out. Is it possible to create such experience with WiX? also is it possible in future to upgrade only one of those components?
Yes, Wix it brilliant for this kind of thing, it calls them Features, you can simply setup a set of features (you can set the Level so that things you want installed by default (if you do) are checked, and things that are optional are unchecked (if you like). You can also have a feature under a feature, for children like:
Product
-Feature 1
-Feature 2
--Feature 2 Documentation
--Feature 2 Admin Tools
-Feature 3
(etc)
These support title/description etc to make it nice and user friendly.
To setup the more advances UI features you will need to add a reference to the WixUIExtension.dll to the installer project, and add a UIRef element into the product (see this article) like:
<UIRef Id="WixUI_FeatureTree" />
You'll probably want to setup a Feature for each of the "things" you want installed, then setup a ComponentGroup for each one, in that you can define any number of sub components that you want installed.
Here's a snippet that should do the above (note it's not fully fleshed out, just an example):
<UIRef Id="WixUI_FeatureTree" />
<ComponentGroup Id="Component1">
<ComponentRef Id="Component1"/>
</ComponentGroup>
<Component Id="Component1" Directory="directorytobeinstalledto">
<File Id="File1" Source="fileweareinstalling"/>
</Component>
<Feature Id="Feature1" Title="Feature 1" Description="My Feature 1" Level="1">
<ComponentGroupRef Id="Component1"/>
</Feature>
<Feature Id="Feature2" Title="Feature 2" Description="My Feature 2" Level="1">
<Feature Id="Feature2.Docs" Title="Feature 2 Documentation" Description="My Feature 2 Documentation" Level="1000"/>
<Feature Id="Feature2.Admin" Title="Feature 2 Admin Tools" Description="My Feature 2 Administration Tools" Level="1000"/>
</Feature>
<Feature Id="Feature3" Title="Feature 3" Description="My Feature 3" Level="0"/> <!-- disabled! -->

WiX: Define a File component that may not exist

I need to define a Wix file component that may not exist in certain circumstances. Is there any way to do this? Condition elements in Wix all seem to work at install time, and I need something that'll detect at compile time if a file is present and build the installer accordingly.
It seems you need to check out the wix preprocessor. Check out wix documentation on the topic:
wix preprocessor
for example, suppose you have an environment variable called APPTYPE. If its value is set to 'Full', then MyApp_Full.exe will be included and processed by the wix compiler (candle).
<Component Id='MyComponent1' Guid='fff60f72-5553-4e6b-9bf0-ad62ab9a90b1'>
<?if $(env.APPTYPE) = Full?>
<File Name='MyApp_Full.exe' DiskId='1' Source='..\MyApp_Full.exe' Vital='yes' />
<?endif?>
...
</Component>
There is more! Variables, defines, conditionals. Check out that doc page.
As iwo said, preprocessor variables are your friend! However the example from iwo can (and will) violate component rules, as the component isn't 'stable'. Better to condition an entire component (or component group)...
<?if $(var.releasetype)=full ?>
<ComponentRef Id="Somefile.dll" />
<?elseif $(var.releasetype)=enterprise ?>
<ComponentGroupRef Id="SomethingElse" />
<?endif?>
And then include the Component and ComponentGroups in separate Fragment tags so that they will only be compiled when referenced :)
<Fragment>
<Component Id="Somefile.dll" Guid="*">
<File Id="Somefile.dll" KeyPath="yes" Source="SourceDir\Somefile.dll" />
</Component>
</Fragment>
<Fragment>
<ComponentGroup Id="SomethingElse">
<ComponentRef Id="Somefile.dll" />
<Component Id="AnotherFile.dll>
<File Id="AnotherFile.dll" KeyPath="yes" Source="SourceDir\AnotherFile.dll" />
</Component>
</ComponentGroup>
</Fragment>
Personally I use nant to call candle and light targets, defining different variables for various different builds and products, effective use of fragments and preprocessor variables provides a great opportunity for code re-use between projects, or various releases of the same project.
In your case, to check if a file exists... then you'd just use the internal functions to define, or redefine a variable that is later passed to WiX. e.g.:
<if test="${not file::exists('something.dll')}">
<property name="releasetype" value="blahblahblah" />
</if>

writing registry in wix - problem illustrated with sample wxs file

I am trying to write to registry using Wix.
it is failing showing the error
"The error code is 2727"
to run this sample follow the below steps.
you need a text file in c:\testinstall.txt
it installs the file testinstall.txt in
C:\Program Files\testinstall
candle sample.wxs
light sample.wixobj
sample.msi will be created
when i add this entry in the script
it is failing.
all i need is to have a script which will create a key and write some value into the
registry.
sample.wxs code
2
<Registry Id="TestKey"
Root="HKLM"
Key="SOFTWARE\testCorp"
Action="createKeyAndRemoveKeyOnUninstall">
<Registry Id="TestValue"
Name="TestValue"
Action="write"
Value="123"
Type="string" />
</Registry>
</Component>
</Directory>
</Directory>
</Directory>
<Feature Id="Feature" Level="1">
<ComponentRef Id="component0" />
<ComponentRef Id="ID0EAAA" />
</Feature>
Are you using WiX v2? Instead of creating the registry value with two Registry entries, just combine it all into one line.
<Registry Id="TestKey" Root="HKLM" Key="SOFTWARE\testCorp" Name="TestValue" Value="123" Type="string" Action="write" />
That's usually a lot easier. If you really want to nest them then I recommend leaving the Registry/#Action attribute off of the parent registry key so it doesn't actually end up in the MSI. Just organizes the child elements.
Note the syntax is a bit different in WiX v3.