<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" UpgradeCode="1" Version="1.0.0.0" Language="1033" Name="My Application Name" Manufacturer="My Manufacturer Name">
<Package InstallerVersion="300" Compressed="yes"/>
<Media Id="1" Cabinet="myapplication.cab" EmbedCab="yes" />
<!-- Step 1: Define the directory structure -->
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="APPLICATIONROOTDIRECTORY" Name="My Application Name"/>
</Directory>
</Directory>
<!-- Step 2: Add files to your installer package -->
<!-- Copied from output from heat.exe -->
<Fragment>
<DirectoryRef Id="TARGETDIR">
<Directory Id="dirBF6284DAE096656A1A0B06AE3DCAA0C9" Name="MyAppName">
<Component Id="cmp26BABDEF350D4D06E3894ED92A9EA86E" Guid="8E1DA6FE-08EA-4D2E-8EBA-85131387A359">
<File Id="filEBD2DA63132D753815D44CEDC2ED5E88" KeyPath="yes" Source="SourceDir\benutzer.csv" />
</Component>
</Directory>
</DirectoryRef>
</Fragment>
<Fragment>
<ComponentGroup Id="MyComponentGroup">
<ComponentRef Id="cmp26BABDEF350D4D06E3894ED92A9EA86E" />
</ComponentGroup>
</Fragment>
<!-- Step 3: Tell WiX to install the files -->
<Feature Id="MainApplication" Title="Main Application" Level="1">
<ComponentGroupRef Id="MyComponentGroup" />
</Feature>
</Product>
</Wix>
Error:
error LGHT0094 : Unresolved reference to symbol ’Component:MyComponentGroup’ in section ’Product:*’.
I reduced the full code for this example, normally I would have many more files to be packaged. The component harvesting is done by heat.exe, I copied the components part into this wix file.
Although the error indicates what is the problem, I don't know what exactly to look for.
The code is run from a bat-file:
set WIX_BIN=c:\Program Files (x86)\WiX Toolset v3.11\bin\
echo Wix Toolset Bin Path: %WIX_BIN%
"%WIX_BIN%candle.exe" out.wxs -ext WixUtilExtension
if exist out.wixobj (
"%WIX_BIN%light.exe" -out out.msi out.wixobj -ext WixUIExtension -ext WixUtilExtension
)
pause
Related
I am trying to build my first installer using WIX. I am not using visual studio instead i am using command line. I have a wxs file and i have also created a .wxi file for the Headers and i have defined them buy i get the following error when i run the candle.exe "Undefined preprocessor variable '$(var.ProjectDir)'"
Here is the .wxs and .wxi
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="{CB06C559-BCBF-4C85-95F3-FE55F6F50463}" Name="My first msi installer" Language="1033" Version="1.0.0.0" Manufacturer="Wave-axis" UpgradeCode="9be991bb-ceb1-4320-bfc7-56738e32c99a">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<Icon Id="icon.ico" SourceFile="$(var.ProjectDir)icon.ico" />
<Property Id="WAVEAXIS" Value="icon.ico" />
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate />
<UIRef Id="WixUI_Minimal" />
<!--used for the UI for the installer-->
<Feature Id="ProductFeature" Title="My first msi installer" Level="1">
<!-- This includes all the feature of the installer-->
<ComponentGroupRef Id="ProductComponents" />
<ComponentRef Id="ApplicationShortcut" />
<!--Used for shortcut on the start up menu-->
<ComponentRef Id="ApplicationShortcutDesktop" />
<!--used for desktop shortcut-->
</Feature>
</Product>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<!--install location of the application-->
<Directory Id="INSTALLFOLDER" Name="My first msi installer" />
</Directory>
<Directory Id="ProgramMenuFolder">
<!--install location for the startup-->
<Directory Id="ApplicationProgramsFolder" Name="My first msi installer" />
</Directory>
<Directory Id="DesktopFolder" Name="Desktop" />
<!--install loaction for the desktop-->
</Directory>
</Fragment>
</Wix>
.wxi code
<?xml version="1.0" encoding="utf-8"?>
<Include xmlns="http://schemas.microsoft.com/wix/2006/wi">
<?define firstapplication.TargetDir ?>
<?define ProjectDir ?>
<?define firstapplication_TargetDir ?>
<?define ProductId=652648517 ?>
</Include>
regards Sagar
You need to include your wxi file in every wxs file you wish to use the properties in at the top of your file before the <Wix> tag
<?include $(sys.SOURCEFILEDIR)Path\to\InstallVars.wxi?>
<Wix xmlns="http://...">
...
</Wix>
This page will explain some of the available variables for the preprocessor like "SOURCEFILEDIR".
I have used Wix on and off for almost a year. After a little break and now I am back to wix and need to build a wix Msi again but I found a very strange thing that I haven't met before. After I created the msi file and and copy the msi to somewhere to install. During the installation, it shows an error that it can't find the source files from the folder: current msi location\EasyLobby\Cogito. I was wondering why it tried to find the source files from that location. I then found that from the project during the compilation, it always creates \EasyLobby\Cogito under the bin\Debug folder. So if I run the msi right from the ...bin\Debug, it runs OK because the \EasyLobby\Cogito folder is there. \
It seems so strange. The msi file should include all the source files and shouldn't look for source files somewhere else. Here is the product.wxs file:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" Name="SetupCogito" Language="1033" Version="2.0.0.0" Manufacturer="Microsoft" UpgradeCode="96cb03c9-6a03-4344-b816-20a0bb9e5df0">
<Package InstallerVersion="200" Compressed="no" InstallScope="perMachine" />
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<Media Id="1" Cabinet="Server.cab" EmbedCab="yes" />
<!--<MediaTemplate />-->
<Feature Id="ProductFeature" Title="SetupCogito" Level="1">
<ComponentGroupRef Id="ComponentGroup"/>
<ComponentRef Id="EasyLobbyCogitoShortcut" />
</Feature>
<WixVariable Id="WixUILicenseRtf" Value="Files\LicenseAgmt.rtf"/>
<UIRef Id="CogitoUI_Installdir" />
<Property Id="WIXUI_INSTALLDIR" Value="COGITOFOLDER" />
<Binary Id="banner_bmp" SourceFile="Files\Banner.bmp"/>
<Property Id ="PIDTemplate" >
<![CDATA[&&&-&&&&&&-&&&&-&&&&]]>
</Property>
<Icon Id="ELCogitoConfig.exe" SourceFile="..\CogitoIntegration\ELCogitoConfig.exe" />
</Product>
<Fragment>
<Binary Id="CustomActions"
SourceFile="..\CustomActions\bin\Debug\CustomActions.CA.dll" />
<CustomAction Id="IsValidKeyCode"
BinaryKey="CustomActions"
DllEntry="IsValidKeyCode"
Execute="immediate"
Return="check" />
<InstallExecuteSequence>
<Custom Action="IsValidKeyCode"
Before='InstallFinalize'>NOT Installed</Custom>
</InstallExecuteSequence>
</Fragment>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="EasyLobby" >
<Directory Id="COGITOFOLDER" Name="Cogito"/>
</Directory>
</Directory>
<Directory Id="ProgramMenuFolder">
<Directory Id="ApplicationProgramsFolder" Name="EasyLobby Cogito" />
</Directory>
</Directory>
</Fragment>
<Fragment>
<DirectoryRef Id="COGITOFOLDER">
<Component Id="EasyLobbyCogitoShortcut" Guid="{BFE6EB30-0F71-4F92-8D93-84B4EBF41F0E}" >
<File Id="Easy" Source="$(var.SourceDir)\ELCogitoConfig.exe" />
<Shortcut Id="ApplicationStartMenuShortcut" Name="Cogito Configuration" Directory="ApplicationProgramsFolder"
WorkingDirectory='INSTALLDIR' Icon="ELCogitoConfig.exe" IconIndex="0" Advertise="yes"/>
</Component>
</DirectoryRef>
And this is the config for heat in project file:
<Target Name="BeforeBuild">
<PropertyGroup>
<DefineConstants>SourceDir= C:\Development\SetupCogito\CogitoIntegration;</DefineConstants>
<LinkerBaseInputPaths>..\CogitoIntegration\</LinkerBaseInputPaths>
</PropertyGroup>
<HeatDirectory OutputFile="CogitoSetup.wxs" Directory="..\CogitoIntegration" PreprocessorVariable="var.SourceDir" DirectoryRefId="COGITOFOLDER" ComponentGroupName="ComponentGroup" SuppressCom="true" SuppressFragments="true" SuppressRegistry="true" SuppressRootDirectory="true" AutoGenerateGuids="false" GenerateGuidsNow="true" ToolPath="$(WixToolPath)" />
This line here is your problem:
<Package InstallerVersion="200" Compressed="no" InstallScope="perMachine" />
Change Compressed=no to Compressed=yes and it will include all the source files in the finished MSI. If you don't compress it, the finished files are not included in the MSI and you get an error if it can't find them at runtime.
See Package reference.
I am trying to install some files to WindowsFolder. Here is the markup:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" Name="MyAppSetup" Language="1033" Version="1.0.0.0" Manufacturer="abc" UpgradeCode="C313D73A-0FE5-496C-BD86-C21565BD65ED">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate />
<Feature Id="ProductFeature" Title="MyAppSetup" Level="1">
<ComponentGroupRef Id="ProductComponents" />
</Feature>
</Product>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="WindowsFolder">
<Directory Id="INSTALLFOLDER" />
</Directory>
</Directory>
</Fragment>
<Fragment>
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
<Component Id="myApp1" Guid="13B43FD7-8D69-4D2E-BF03-B3EC5679D78A">
<File Id="myApp.pdb" Source="myApp64.pdb" KeyPath="yes" />
</Component>
<Component Id="myApp2" Guid="23B43FD7-8D69-4D2E-BF03-B3EC5679D78A">
<File Id="myApp.sys" Source="myApp64.sys" KeyPath="yes" />
</Component>
<Component Id="myApp3" Guid="33B43FD7-8D69-4D2E-BF03-B3EC5679D78A">
<File Id="myAppsvc.exe" Source="myAppsvc64.exe" KeyPath="yes" />
</Component>
<Component Id="myApp4" Guid="43B43FD7-8D69-4D2E-BF03-B3EC5679D78A">
<File Id="myAppsvc.pdb" Source="myAppsvc64.pdb" KeyPath="yes" />
</Component>
</ComponentGroup>
</Fragment>
</Wix>
Based on my reading, this directory element specifies the files to be installed/copied under WindowsFolder (on my machine C:\windows), but instead, it installs files to D:\ which has the most space. So the question is : what did I do wrong on the directory?
It turns out that the Directory reset happens when the msi is launched through msiexec using /a (admin) option. Here is a few log entries show this:
PROPERTY CHANGE: Adding TARGETDIR property. Its value is 'D:\'.
PROPERTY CHANGE: Modifying WindowsFolder property. Its current value is 'C:\windows\'. Its new value: 'D:\'.
PROPERTY CHANGE: Adding APPLICATIONROOTDIRECTORY property. Its value is 'D:\'.
If msi is launched using /i option, then the Directory reset is not happening. Since package needs to be installed with elevated privilege, the correct way to do this is using /i option in a elevated CMD console. The markup was never the issue.
I'm aware of similar questions inside stackoverflow:
WIX:default directory in WixUI_InstallDir,
WIX installer root directory and versioning,
Is it possible to have two root directories in WIX,
copy file to custom dir in another partition,
How to create a directory in wix?
however none of them shows a simple and immediate code to create a folder inside the C:\ folder (not hard coded but should be the root disk or system disk or whatever you would call the disk which contains the Windows folder) and to copy files inside it.
In other words how can Wix create a C:\MynewDir\example.jar folder?
Here's what I tried:
<?xml version="1.0" encoding="UTF-8"?>
<!-- WiX installer MyProgram by Mark Seuffert -->
<?define ProductVersion = "13.1.2.3"?>
<?define ProductUpgradeCode = "12345678-1234-1234-1234-111111111112"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" UpgradeCode="$(var.ProductUpgradeCode)" Name="MyProgram" Version="$(var.ProductVersion)" Manufacturer="COMPANY" Language="1033">
<Package InstallerVersion="200" Compressed="yes" Comments="Windows Installer Package" />
<Media Id="1" Cabinet="product.cab" EmbedCab="yes" />
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLDIR" Name="MyProgram">
<Component Id="ApplicationFiles" Guid="12345678-1234-1234-1234-222222222222">
<File Id="ApplicationFile1" Source="C:\Users\user\Desktop\myprogram.exe" />
</Component>
</Directory>
</Directory>
<Directory Id="ANOTHERLOCATION" FileSource="C:\MynewDir">
</Directory>
</Directory>
<DirectoryRef Id="ANOTHERLOCATION" FileSource="C:\MynewDir">
<Component Id="ApplicationFiles2" Guid="12345678-1234-1234-1235-111111111111">
<File Id="ApplicationFile2" Source="C:\Users\user\Desktop\InstallerFiles_13_4_9_3\myprogramLauncher.jar" />
<CreateFolder />
</Component>
</DirectoryRef>
<InstallExecuteSequence>
<RemoveExistingProducts After="InstallValidate" />
</InstallExecuteSequence>
<Feature Id="DefaultFeature" Level="1">
<ComponentRef Id="ApplicationFiles2" />
<ComponentRef Id="ApplicationFiles" />
</Feature>
</Product>
</Wix>
EDIT 1:
Yan Sklyarenko just found what I was looking for, that's the WindowsVolume (I don't know how I missed it inside http://msdn.microsoft.com/en-us/library/windows/desktop/aa370905%28v=vs.85%29.aspx#system_folder_properties microsoft document).
However how do I replace FileSource="C:\MynewDir" with FileSource="[WindowsVolume]MynewDir" ??? because apparently even with WINDOWSVOLUME the resulting volume chosen is always D:\ in my computer which has more available space :(
EDIT 2 I updated my code using Yan Sklyarenko's second sample ( ####newpart#### identifies parts where code differs), however behaviour is still the same, the installer chooses the disk with more free space (D:\ in my case) and not C:\ where windows is..
<?xml version="1.0" encoding="UTF-8"?>
<!-- WiX installer MyProgram by Mark Seuffert -->
<?define ProductVersion = "13.1.2.3"?>
<?define ProductUpgradeCode = "12345678-1234-1234-1234-111111111112"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" UpgradeCode="$(var.ProductUpgradeCode)" Name="MyProgram" Version="$(var.ProductVersion)" Manufacturer="COMPANY" Language="1033">
<Package InstallerVersion="200" Compressed="yes" Comments="Windows Installer Package" />
<Media Id="1" Cabinet="product.cab" EmbedCab="yes" />
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLDIR" Name="MyProgram">
<Component Id="ApplicationFiles" Guid="12345678-1234-1234-1234-222222222222">
<File Id="ApplicationFile1" Source="C:\Users\user\Desktop\myprogram.exe" />
</Component>
</Directory>
</Directory>
<Directory Id="ANOTHERLOCATION" FileSource="C:\MynewDir">
####newpart####<Component Id="ApplicationFiles2" Guid="12345678-1234-1234-1235-111111111111">
<File Id="ApplicationFile2" Source="C:\Users\user\Desktop\InstallerFiles_13_4_9_3\myprogramLauncher.jar" />
<CreateFolder />
</Component>
</Directory>
</Directory>
####newpart####<SetDirectory Id="ANOTHERLOCATION" Value="[WINDOWSVOLUME]" />
<InstallExecuteSequence>
<RemoveExistingProducts After="InstallValidate" />
</InstallExecuteSequence>
<Feature Id="DefaultFeature" Level="1">
<ComponentRef Id="ApplicationFiles2" />
<ComponentRef Id="ApplicationFiles" />
</Feature>
</Product>
</Wix>
EDIT 3 The last code snippet above should work however change the casing of WINDOWSVOLUME to WindowsVolume as suggested.
Here is a complete working solution based on your code simplified (notice the comment in the code):
<?define ProductVersion = "13.1.2.3"?>
<?define ProductUpgradeCode = "12345678-1234-1234-1234-111111111112"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" UpgradeCode="$(var.ProductUpgradeCode)" Name="MyProgram"
Version="$(var.ProductVersion)" Manufacturer="COMPANY" Language="1033">
<Package InstallerVersion="200" Compressed="yes" />
<Media Id="1" Cabinet="product.cab" EmbedCab="yes" />
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLDIR" Name="MyProgram" />
<Directory Id="ANOTHERLOCATION" />
</Directory>
</Directory>
<!-- The casing of 'ANOTHERLOCATION' and 'WindowsVolume' is very important here.
Replace 'MyNewDir' with the correct name of the folder you want on
WindowsVolume.
-->
<SetDirectory Id="ANOTHERLOCATION" Value="[WindowsVolume]MyNewDir" />
<Feature Id="DefaultFeature" Level="1">
<Component Directory="INSTALLDIR">
<File Id="ApplicationFile1" Source="C:\Users\user\Desktop\myprogram.exe" />
</Component>
<Component Directory="ANOTHERLOCATION">
<File Id="ApplicationFile2" Source="C:\Users\user\Desktop\InstallerFiles_13_4_9_3\myprogramLauncher.jar" />
</Component>
</Feature>
</Product>
</Wix>
Ok, you can do something like this:
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="WindowsVolume">
<Directory Id="MyNewDirId" Name="MyNewDir">
<Component Id="SampleComponent" Guid="...">
<File Id="SampleFile" Source="..." KeyPath="yes" />
</Component>
</Directory>
</Directory>
</Directory>
This will install the file to the MyNewDir folder on Windows drive (C: in my case).
However, it will complain that using WindowsVolume in this fashion might have unexpected side effects.
To satisfy that validation, you can change the sample to:
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="MyNewDirId" Name="MyNewDir">
<Component Id="SampleComponent" Guid="...">
<File Id="SampleFile" Source="..." KeyPath="yes" />
</Component>
</Directory>
</Directory>
<SetDirectory Id="MyNewDirId" Value="[WindowsVolume]MyNewDir" />
This looks more like a hack, but the result is the same.
To be honest, I don't understand what those "unexpected side effects" could be. Maybe, Windows Installer gurus can shed some light on this.
Hope this helps.
I am having trouble understanding wix documentation. I have created a simple installer that allows user to select a destination folder for app. It looks something like this:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" Name="AppName" Language="1033" Version="1.0.0.0" Manufacturer="Manufacturer" UpgradeCode="guid">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate />
<Feature Id="ProductFeature" Title="SetupProjectFeature" Level="1">
<ComponentGroupRef Id="ProductComponents" />
</Feature>
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLFOLDER" />
<UIRef Id="WixUI_InstallDir"/>
</Product>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="OeeCoach" />
</Directory>
</Directory>
</Fragment>
<Fragment>
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
<!-- TODO: Insert files, registry keys, and other resources here. -->
<Component Id="EntityFramework" Guid="guid">
<File Id="EntityFramework.dll" Source="../App/bin/Release/EntityFramework.dll" KeyPath="yes" />
</Component>
<Component Id="MvvmLight.Extras" Guid="guid">
<File Id="GalaSoft.MvvmLight.Extras.WPF4.dll" Source="../App/bin/Release/GalaSoft.MvvmLight.Extras.WPF4.dll" KeyPath="yes" />
</Component>
</ComponentGroup>
</Fragment>
</Wix>
Now I need to check for .net 4 and its prerequisites, but I could not understand hot to do this. Documentation says that I need to use Bundle element, but compiler seems to complain when it is together with Product element in same wix file.
Any help is appreciated.
The bootstrapper is a separate project from your setup project. If you are using Visual Studio, add a new project to your solution and choose Bootstrapper project (instead of Setup project).