This is my component:
<Component Id="ServiceComponent" Directory="INSTALLFOLDER">
<File Id="ServiceExecutable"
Name="$(var.LoggerService.TargetFileName)"
Source="$(var.LoggerService.TargetPath)"
Vital="yes"
KeyPath="yes"
DiskId="1" />
...
This is my patch:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'>
<Patch AllowRemoval='yes' Manufacturer='Test Ltd.' MoreInfoURL='www.test.com'
DisplayName='Test Patch' Description='Small Update Patch' Classification='Update'>
<Media Id='5000' Cabinet='Patch.cab'>
<PatchBaseline Id='Sample' />
</Media>
<PatchFamilyRef Id="SamplePatchFamily"/>
</Patch>
<Fragment>
<PatchFamily Id='SamplePatchFamily' Version='1.0.0.0' Supersede='yes'>
<ComponentRef Id='ServiceComponent' />
</PatchFamily>
</Fragment>
</Wix>
This is my patch generator script:
torch.exe -p -xi bin\Debug\1.1\SetupLogger.wixpdb bin\Debug\1.2\SetupLogger.wixpdb -out diff.wixmst
candle.exe patch.wxs
light.exe patch.wixobj -out patch.wixmsp
pyro.exe patch.wixmsp -out patch.msp -t Sample diff.wixmst
If I modify the file ServiceExecutable in the same path $(var.LoggerService.TargetPath) then Wix doesn't detect any change and saying to me:
warning PYRO1079 : The cabinet 'Patch.cab' does not contain any files. If this patch contains no files, this warning can likely be safely ignored. Otherwise, try passing -p to torch.exe when first building the transforms, or add a ComponentRef to your PatchFamily authoring to pull changed files into the cabinet.
diff.wixmst : error PYRO0227 : The transform being built did not contain any differences so it could not be created.
However, if I modify the file ServiceExecutable and put it in the new dir, then specify that new dir in the File source tag, then the change is picked up by Wix and everything is fine.
Question: how can I make Wix to detect the change without changing source path? I think Wix should be able to detect change because the checksum of the KeyPath file has been changed.
Related
How do I make the sources specified in a heat generated file visible to the build?
I've got a project named Foo and a project named FooSetup. They have the same parent directory. To generate the list of files to install I ran in FooSetup:
heat dir "..\Foo\bin\Release" -cg "SomeGroupName" -ag -template:fragment -out heat.wxs
Now when I try to build the installer, I get:
The system cannot find the file 'SourceDir\Foo.dll'.
(that file does exist in the Release directory)
The path to Foo\bin\Release is specified in include paths in the FooSetup project properties.
What am I missing here - why is none of the listed files found?
WiX Learning Resources: A couple of links to resources on WiX:
Click-by-click WiX and Visual Studio
Long list of WiX links
WiX Preprocessor Variables: What is SourceDir? Rob Mensching (WiX creator) on SourceDir.
As explained here you can change SourceDir to a compiler variable:
Heat.exe: Something like this:
"%WIX%bin\heat.exe" dir . -sfrag -suid -ag -var MyReleasePath -out MySource.wxs
You will get something like this:
<!-- Extract -->
<Component Id="MyFile.exe" Guid="*">
<File Id="MyFile.exe" KeyPath="yes" Source="$(MyReleasePath)\MyFile.exe" />
</Component>
<!-- End of Extract -->
WiX Sample: Then you insert this into your source. Something like this:
<!-- START OF COMPILER VARIABLES: -->
<?define MyVersion = "1.0.0.0" ?>
<?define MyReleasePath = "C:\My Releases\Wix Testing\" ?>
<!-- END OF COMPILER VARIABLES: -->
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" Name="WiX Testing" Language="1033" Version="$(var.MyVersion)"
Manufacturer="WiX Testing" UpgradeCode="PUT-GUID-HERE">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<!-- Enable line below for GUI in MSI -->
<!-- <UIRef Id="WixUI_Mondo" /> -->
<MediaTemplate EmbedCab="yes" />
<Feature Id="Main" Title="Main Feature" Level="1" />
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="WiX Testing">
<!-- Essential part follows: -->
<Component Feature="Main">
<File Source="$(var.MyReleasePath)MyFile.exe"></File>
</Component>
<!-- End of Essential part -->
</Directory>
</Directory>
</Directory>
</Product>
</Wix>
Batch File Compile: Visual Studio takes care of most of the build issues once you have defined the variables. If you want to compile "manually", here is a quick sample:
"%WIX%bin\candle.exe" MySource.wxs -ext WixUIExtension >> Build.log
"%WIX%bin\light.exe" -out Test.msi MySource.wixobj -ext WixUIExtension >> Build.log
Links:
WiX sample for other issue at bottom
WiX 3.11.1 on Windows 10 Pro Version 1703 64-bit. NOT using Visual Studio. Using simple text files as follows.
Here is a test case of the situation I am finding.
myapp.wxs is this:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:netfx="http://schemas.microsoft.com/wix/NetFxExtension">
<Product Id="*"
Name="MyApp"
Language="1033"
Version="1.0.0.0"
Manufacturer="Me"
UpgradeCode="PUT-GUID-HERE">
<Package InstallerVersion="301"
Compressed="yes"
InstallScope="perMachine"
Manufacturer="Me"
Description="My App"
Keywords=".NET,Installer,MSI" />
<MediaTemplate EmbedCab="yes" />
<UIRef Id="WixUI_Minimal" />
<UIRef Id="WixUI_ErrorProgressText" />
<!-- ****************************************** -->
<WixVariable Id="WixUIDialogBmp"
Value="[CMP_Refresh_file]" />
<!-- ****************************************** -->
<Feature Id="MyFeature"
Title="MyApp Feature"
Description="Installs MyApp"
Level="1">
</Feature>
</Product>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="TestFolder" Name="TESTfolder" />
</Directory>
<Component Id="CMP_Refresh_file" Guid="*" Directory="TESTfolder">
<File Id="FILE_RefreshPNG" Source= "Refresh.png" KeyPath="yes" />
</Component>
</Fragment>
</Wix>
myapp.bat is:
"C:\Program Files (x86)\WiX Toolset v3.11\bin\candle.exe" myapp.wxs
"C:\Program Files (x86)\WiX Toolset v3.11\bin\light.exe" myapp.wixobj -ext WixUIExtension -ext WixUtilExtension
#pause
When I run the .bat file, it cannot find the CMP_Refresh_file (error LGHT0103 : The system cannot find the file). The folder TESTfolder is a direct sub-folder of the folder in which the .wxs file exists.
Substituting the full file path solves the issue. BUT that is not what I want as I will have a multitude of files and folders. (Also, if I put the file in the same folder as the .wxs file, of course, it finds it.)
I suspect it is purely a syntactic issue caused by my ignorance. In any case, I have tried endless variations of syntax for the Value of WixUIDialogBmp without joy (except the full name).
Help to resolve very much appreciated. Thanks!
Looking at your WiX code I can see that you are getting confused between the MSI destination and the source folder paths. The Directory tag is to create a folder on the machine where you run the MSI (where you want to deploy your application) - it has nothing to do with the source folders from where you package your files.
Replace your filepath with:
<File Id="FILE_RefreshPNG" Source= "\TESTfolder\Refresh.png" KeyPath="yes"/>
As you can see, the file -> source attribute path should be written with reference to your WXS file path.
If you are planning to deploy the refresh.png underneath the testfolder on the client machines then you got to move to closing </Directory> tag right after your <File> tag
Try <WixVariable Id="WixUIDialogBmp" Value="[#CMP_Refresh_file]" /> which references the installed path. See Formatted Strings for more info.
Came across this while trying to figure out a different issue with source file resolution. Isaiah4110's answer is misleading. The <Directory> structure can specify both the destination on the target machine and where to find the source files as long as the directory structure is the same. You just have to nest your <Component> elements within the corresponding directory elements and specify the Name attribute rather than Source.
In this case, the following should work:
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="TestFolder" Name="TESTfolder">
<Component Id="CMP_Refresh_file" Guid="*">
<File Id="FILE_RefreshPNG" Name="Refresh.png" KeyPath="yes" />
</Component>
</Directory>
</Directory>
This works because the Source of a <File> defaults to the source path of the <Component>'s parent <Directory> element (if there is one) plus the Name. See: File element reference and How to specify source files. Unfortunately this logic does not seem to work when placing the <Component> outside of the <Directory> structure as the example in the question does.
I am running the following command:
heat.exe dir bin\Release -sfrag -sreg -var var.sourcebin -dr myappfolder -cg myapp_comp_group
This generates a nice wxs file that looks a bit like this:
<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<ComponentGroup Id="myapp_comp_group">
<ComponentRef Id="cmpE519314043C2FFE1104E067D33CBC652" />
<ComponentRef Id="cmp0431CFEC47E793CE59C185A8BDD9D865" />
</ComponentGroup>
</Fragment>
<Fragment>
<DirectoryRef Id="myappfolder">
<Directory Id="dir4ADCEBD4F8C9DC384017088D96B7A1C3" Name="somebinfolder">
<Component Id="cmpE519314043C2FFE1104E067D33CBC652" Guid="EB84C1A8-7BF5-4967-878D-8DAD9DFFA0A6">
<File Id="filD8C8D39058B0FF5C9608B1F99B0CD5BA" KeyPath="yes" Source="$(var.sourcebin)\app.config" />
</Component>
</Directory>
</DirectoryRef>
</Fragment>
</Wix>
I am using this by heat generated wxs file in my project, but I get an error, because the $(var.sourcebin) has not been set.
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<?define sourcebin="C:\svn\myapp\bin\Release"?>
<!-- leaving some stuff out of course -->
<Module>
<ComponentGroupRef Id="myapp_comp_group"/>
</Module>
</Wix>
error CNDL0150: Undefined preprocessor variable '$(var.sourcebin)'.
How do I define this variable so it is picked up by the heat generated file? I don't want to change the heat generated file manually, because it is re-generated every time.
Open project Properties, Choose Build tab and add preprocessor variable as needed.
sourcebin="C:\svn\myapp\bin\Release";
In the define section use:
<?define sourcebin = $(var.sourcebin)?>
Heat command you can leave as it is.
This will be the same when you will need to pass variables from msbuild (Wixproj file) to other files in your project(wxs,wxi...). Common use when using TFS.
I'm trying to create a patch using WiX 3.6 following this example containing 2 C# projects (executable and library). But I'm getting this error:
warning PYRO1079 : The cabinet 'RMT.cab' does not contain any files. If this patch contains no files, this warning can likely be safely ignored. Otherwise, try passing -p to torch.exe when first building the transforms, or add a ComponentRef to your PatchFamily authoring to pull changed files into the cabinet.
error PYRO0227 : The transform being built did not contain any differences so it could not be created.
Executed commands:
set w="c:\Program Files (x86)\WiX Toolset v3.6\bin\"
%w%torch.exe -p -xi 1.0.0.0\PatchMe.Installer.wixpdb 1.1.1.1\PatchMe.Installer.wixpdb -out Patch\Diff.wixmst
%w%candle.exe Patch.wxs
%w%light.exe Patch.wixobj -out Patch\Patch.WixMsp
%w%pyro.exe Patch\Patch.WixMsp -out Patch\Patch.msp -t RTM Patch\Diff.wixmst
Directories "1.0.0.0" and "1.1.1.1" contain output of two different versions of same projects (changed AssemblyVersion and some code changes).
Patch.wxs file:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<?include Variables.wxi ?>
<Patch AllowRemoval="yes"
Manufacturer="$(var.Manufacturer)"
DisplayName="$(var.ProductName) $(var.ProductVersion)"
Description="Small Update Patch"
Classification="Update"
TargetProductName="$(var.ProductName)"
>
<Media Id="5000" Cabinet="RMT.cab">
<PatchBaseline Id="RTM">
</PatchBaseline>
</Media>
<PatchFamilyRef Id="SamplePatchFamily"/>
</Patch>
<Fragment>
<PatchFamily Id="SamplePatchFamily" Version="$(var.ProductVersion)" Supersede="yes">
<ComponentRef Id="cmp981D9885AA29DD578D66D32ED919EBFB"/>
<ComponentRef Id="cmpD5E6EA59DB565F052E0217CB3248DAE5"/>
</PatchFamily>
</Fragment>
</Wix>
ComponentRef Id's refers to component fragments create by heat.exe harvest of projects mentioned earlier.
Any idea, what could be a problem and why transform doesn't contain any changes?
I think this may be a bug in 3.6. I tried for several hours to get this to work with version 3.6.3303.1, but I always got the PYRO1079 error. I finally downgraded to version 3.5.2519.0, and the error has not reoccurred.
I had to give up my MediaTemplate node and the Directory attribute of my ComponentGroup node after downgrading. I don't know if this was part of the solution or not (i.e. this might have fixed the problem instead of the downgrade).
I am struggling with creating a patch purely using WIX and I was hoping if someone could guide me in the right direction.
I have a few hundred source files and I run heat against them to create a harvest file followed by creating a package using candle and light.
I need to change a few configuration files and I create a 2nd package with the changes.
Using Torch and pyro I create the .wixmst file and then when trying to create the msp file, pyro complains with the following error.
pyro.exe : error PYRO0252 : No valid transforms were provided to attach to the patch. Check to make sure the transforms you passed on the command line have a matching baseline authored in the patch. Also, make sure there are differences between your target and upgrade.
my question really is: what should patch.wxs contain?
Here is what my patch.wxs looks like:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Patch
AllowRemoval="yes"
Manufacturer="sample llc"
MoreInfoURL="sample.com"
DisplayName="Env Patch"
Description="Env Specfic Patch"
Classification="Update"
>
<Media Id="5000" Cabinet="RTM.cab">
<PatchBaseline Id="RTM" />
</Media>
<PatchFamilyRef Id="EnvPatchFamily" />
</Patch>
<Fragment>
<PatchFamily Id='EnvPatchFamily' Version='1.0.0.0' ProductCode="PUT-GUID-HERE" Supersede='yes' >
**********************************************
What component Ref should I put in here
heat creates a component group and I can't
put ComponentGroupRef in here
**********************************************
</PatchFamily>
</Fragment>
</Wix>
I am using Wix patching as described in this link:
http://wix.sourceforge.net/manual-wix3/wix_patching.htm
However, it doesn't consider source wix file created using heat.
Can someone tell me what am I doing wrong here?
Hitesh,
For me heat creates a component group like this:
<Fragment>
<ComponentGroup Id="MyFiles">
<ComponentRef Id="cmp2AA1A30564C621322ECB3CDD70B1C03C" />
<ComponentRef Id="cmp788C978F16E473D4FD85720B5B75C207" />
</ComponentGroup>
</Fragment>
heat command:
"%WIX%\bin\heat.exe" dir slndir\bin\Release -cg MyFiles -gg -scom -sreg -sfrag -srd -dr INSTALLDIR -out ..\Wix\MyFiles.wxs -var var.BinOutputPath -nologo -v -ke -t wixtransform.xsl
And in patch.wxs:
<Fragment>
<PatchFamily Id='ProductPatchFamily' Version='1.3.0.0' Supersede='yes'>
<ComponentRef Id="cmp2AA1A30564C621322ECB3CDD70B1C03C" />
<ComponentRef Id="cmp788C978F16E473D4FD85720B5B75C207" />
</PatchFamily>
</Fragment>
Take care: there is no ProductCode attribute in PatchFamily tag
I would also like to mention that PatchFamily elements are optional when building a patch, and are intended to allow fine grained control over exactly what will get patched. In most cases I find that I want to include all differences between 2 versions of an MSI when building a patch, in which case I omit the PatchFamily altogether. In your case, the resulting patch WXS would look like the following:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Patch
AllowRemoval="yes"
Manufacturer="sample llc"
MoreInfoURL="sample.com"
DisplayName="Env Patch"
Description="Env Specfic Patch"
Classification="Update"
>
<Media Id="5000" Cabinet="RTM.cab">
<PatchBaseline Id="RTM" />
</Media>
</Patch>
</Wix>
I hope this answer helps anyone with a similar question, that is not wanting to manually construct patch families, not wanting to manually includeComponentRef every time they need to build a patch.
I faced the same issue, the fix for this error is to add the GUID to the component and it should remain same for both the versions of msi.
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate />
<Feature Id="ProductFeature" Title="WixPatch" Level="1">
<ComponentGroupRef Id="ProductComponents" />
</Feature>
</Product>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="WixPatch" />
</Directory>
</Directory>
</Fragment>
<Fragment>
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER" >
<Component Id="File1" **Guid="3A64BE7A-BBEC-40AD-8319-45C602734146"**>
<File Source="D:\V2\File1.txt" Name="File1" KeyPath="yes" DiskId="1" Id="F1"/>
</Component>
</ComponentGroup>
</Fragment>