Windows Installer XML relative Path for Patch - msbuild

I'm using the Microsoft Team Foundation Server to manage and Deploy Setups for my Applications.
My Setups are WiX-Setups with relative Paths.
p.e.
Components
<Component Id="Anwendung.exe" Directory="INSTALLLOCATION" Guid="*">
<File Id="Anwendung.exe" KeyPath="yes" Source="$(var.SourceFiles)\Anwendung.exe" />
</Component>
Variables.wxi:
<Include>
<?define SourceFiles = "..\OutputFiles"?>
</Include>
Setups are building correctly.
The Problem: I'm using Torch and Pyro to generate Patches for my applications.
I'm using a pure Wix Patch Project with manipulated build events and additional linker information
(Pre Build - Torch)
(Post Build - Pyro)
(Linker additional Parameters - output as wixmsp)
When I build my Patch, I'm getting 579Failures.
(1x)
Error 776 The command ""C:\Program Files (x86)\WiX Toolset v3.8\bin\pyro.exe" Patch.wixmsp -out Patch.msp -t AnwendungBaseline diff.wixmst" exited with code 103.
C:\Program Files (x86)\MSBuild\Microsoft\WiX\v3.x\wix2010.targets
and (578x)
Error 322 The system cannot find the file '..\SourceFiles\Anwendung.exe'. C:\Patch\Client\Upgrade\Setup\ComponentMain.wxs
I'm sure it's not resolving the paths from the sourcesetups correctly.
Could anybody help me? Rob Arnson , Rob Mensching, Heath Steward? Please :)

To get around issues like this, you can write a custom build activity for TFS to update variables in your WiX config file with fully qualified paths. For instance, you can create a build activity that takes in the path to a config file, the name of a variable, and value for that variable, and then write the new value to the config file. You can keep the config file with relative paths checked into source control, but then the build will update the config file to use the fully qualified path just for the build.
If you are unfamiliar with creating custom build activities, there is a great blog series on it here. The link is for TFS 2010 but the process is similar for TFS 2012.

Related

Add Zip Files to TARGETDIR in WiX

In my Visual Studio 2017 solution, I have a WiX 3 setup project that pulls in the output several other projects (libraries, executables, assets, content). Under the directory structure for the solution but not added to the solution as a project, I have a project that compiles some browser extensions using webpack. This webpack project outputs to an artifacts folder with subdirectories for each browser. Inside each subdirectory is the compiled extension with the version number included in the file name like:
artifacts
Chrome
myextension-0.1.0.0.zip
myextension-0.1.0.1.zip
myextension-0.1.0.2.zip
At compile time, ultimately I want to include the files matching the version number i.e. myextension-\$(var.VERSION).zip into the MSI package so it can then be placed into the application folder during installation. Even when I hard-code the version number i.e. myextension-0.1.0.2.zip into the component, I get an error from light:
LGHT0001: The system cannot find the path specified. (Exception from HRESULT: 0x80070003)
I'm getting the directory with a define like this:
<?define ChromeTargetDir=$(var.SolutionDir)Extensions\artifacts\chrome\?>
And then my component looks like this:
<Component Id="ChromeExt"
Location="local"
Guid="GUID_HERE">
<CreateFolder/>
<File Id="ChromeExtension"
Name="myextension-0.1.0.2.zip"
Source="$(var.ChromeTargetDir)myextension-0.1.0.2.zip"
KeyPath="yes"/>
</Component>
When I look in the wixobj created by candle, I see the full correct path replaced for the file where it resides on my system:
<field>C:\Users\me\source\repos\mysolution\Extensions\artifacts\chrome\myextension-0.1.0.2.zip</field>
So my question is, what is the correct way to include "arbitrary" files in my WiX project?
1) Solution vs Project Dir: The first thing I would try would be to replace $(var.SolutionDir) with $(var.ProjectDir) and try a recompile. I'll follow up if the problem is something else. Let's just rule that out first.
2) Quotes: I also use quotes around my paths:
<?define ChromeTargetDir="C:\Sources\Packages\MyChromeExtension\Files\" ?>
3) Project Variables: And finally you need a reference added to your project for project references and variables to work: WiX: How to use relative path to SolutionDir.
Maybe add: %ProgramFiles (x86)%\WiX Toolset v3.11\bin\WixUIExtension.dll
WiX Documentation: Using Project References and Variables
Obscure: More obscure causes could be lacking access rights (file not seen by the build process and light.exe - running impersonated?). Corrupted file or folder? (try to replace). And whatever else might conspire against you. Locked files?

Patch creation fails (does not spot any differences) on build server

I have a automated Setup creation on our build server, and try to create a patch between the released version and the current build version.
Sadly i can't get it working.
This is my Patch.wxs:
<Patch AllowRemoval="no" Manufacturer="Company" DisplayName="Product Patch" Description="Patch" Classification="Update">
<Media Id="5000" Cabinet="RTM.cab">
<PatchBaseline Id="RTM"/>
</Media>
<PatchFamily Id="SampleFamily" Version="1.0.0.0" Supersede="yes">
<FeatureRef Id="ProductFeature"/>
</PatchFamily>
</Patch>
i use a postBuild to compile&link the patchfile:
"C:\Program Files (x86)\WiX Toolset v3.8\bin\candle.exe" $(ProjectDir)Patch.wxs -dDebug -dOutDir=$(TargetDir) -o Patch.wixobj
"C:\Program Files (x86)\WiX Toolset v3.8\bin\light.exe" $(TargetDir)Patch.wixobj -o $(TargetDir)Patch.wixmsp
Until here everything works fine i guess.
I create a transform using torch after a sucessfull build:
torch -p -xi release.wixpdb latestBuild.wixpdb -out diff.wixmst
The diff is created successfully.
Then pyro gives me an warning that no files are different:
pyro Patch.wixmsp -t RTM diff.wixmst -out patch.msp"
warning PYRO1079 : The cabinet 'RTM.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.
The files are different if i install the msi files i get two different installations. but if i install the patch nothing changes. I played around with the PatchFamily but i can't get it working.
How can i get the Patch file including my changes?
The wix tools is seen to be failing to recognize file content change. To work properly do exactly as described in the WIX tutorial.
Here take special care to add version part in the source of the components, i.e 1.0 take component files from 1.0 source and say 2.0 takes source files from 2.0 root folder. This way file it is creating the patch as expected.
I found out what is causing this problem.
The Build server does not create a separate folder for each Build (just for the Drop, not for the Build itself) so at the time i create a patch both wixpdb files reference the same files of the build folder, thats why there are no differences found. I now changed the buildserver to create a administrative installation inside the drop folder and create a transform using the final msi files.
using the so created transform for pyro creates the msp as expected containing the changed files.

WiX project that references an SSDT project fails to build in TFSBuild - Undefined preprocessor variable '$(var.DatabaseProject.TargetDir)'

My project which is part of a larger solution was converted from a dbproj to asqlproj (SSDT). The solution includes a WiX installer which references the SSDT project. The WiX project builds fine on multiple developer systems through VS2010. The automated builds that we've always used, however, are failing with this error:
error CNDL0150: Undefined preprocessor variable '$(var.DatabaseProject.TargetDir)'.
The solution has been built by TFS automated builds for many months without issue prior to this project being converted. I can see from the build log that the SSDT project is being built, here are some relevant lines from the build log:
Project "C:\B\1\SourcePath\Server\Server.wixproj" (8) is building "C:\B\1\SourcePath\Database\DatabaseProject.sqlproj" (12) on node 1 (default targets).
...
Done Building Project "C:\B\1\SourcePath\Database\DatabaseProject.sqlproj" (default targets).
I can also see that the .dacpac and .dll files for the database project are created and copied into the output directory that TFS build has redirected the projects to.
The reference to the database project seems fine and TFS build seems to know that it should be built, but WiX is complaining about the undefined preprocessor variable for TargetDir.
I must be missing something...Is the output redirect employed by TFS causing my issue? I'm not sure where to go from here and appreciate any help you can suggest.
MORE INFO
Looking at the log file for the build in more detail I can see that the parameters for the .sqlproj project aren't being passed on the command line to candle.exe. When I build locally in VS2010, I can see the expected parameters passed as follows (just like the other projects referenced by the WiX project):
-d"DatabaseProject.FullConfiguration=Release|AnyCPU"
-dDatabaseProject.Platform=AnyCPU
-dDatabaseProject.ProjectDir=C:\SourcePath\Database\
-dDatabaseProject.ProjectExt=.sqlproj
-dDatabaseProject.ProjectFileName=DatabaseProject.sqlproj
-dDatabaseProject.ProjectName=DatabaseProject
-dDatabaseProject.ProjectPath=C:\SourcePath\Database\DatabaseProject.sqlproj
-dDatabaseProject.TargetDir=C:\SourcePath\Database\sql\release\
-dDatabaseProject.TargetExt=.dll
-dDatabaseProject.TargetFileName=DatabaseProject.dll
-dDatabaseProject.TargetName=DatabaseProject
-dDatabaseProject.TargetPath=C:\SourcePath\Database\sql\release\DatabaseProject.dll
None of these parameters are being passed to candle.exe during the TFS build. I figured this information might be useful for helping answer the question.
Any help is greatly appreciated!
Based on #RobMenching's answer, you won't be able to rely on the SSDT project variable to be set by any command-line build, so you'll need to find another way to reference the project's output.
Fortunately, in a standard TFS build, the output folders will be the same for all projects in a given build configuration. Assuming you haven't redirected the output somehow, you should be able to use any of the other projects (which are working properly) as the reference path. E.g., assuming that you have a DatabaseProject.sqlproj and an DataAccessProject.csproj in the solution, you should be able to do:
<Component Id='MyComponent' Guid='12345678-1234-1234-1234-123456789012'>
<?ifdef DatabaseProject.TargetDir ?>
<File Id='foo' Name='foo' src='$(var.DatabaseProject.TargetDir)\foo.dacpac' />
<?else?>
<File Id='foo' Name='foo' src='$(var.DataAccessProject.TargetDir)\foo.dacpac' />
<?endif?>
</Component>
For builds done inside VS2010, where each project is built to its own output folder, the correct preprocessor variable ought to be defined and it will use the first option. For TFS builds, where the preprocessor variable is not defined, TFS will have redirected the SSDT's output to the same folder as all of the other projects, so any one of the preprocessor variables should work just as well.
I believe the root issue here is that the .sqlproj does not support the necessary Visual Studio integration to provide the data for the preprocessor variable. This has created a lot of problems for the WiX toolset over the years. Unfortunately, fixing it requires the owners of the .sqlproj to fix their project system.

Add a folder to installer in wix not files?

My installer has to copy files into installdir... My application has around 2000 files and it is not possible for me to write the script to add each and every file to the installer.
Is there any option in wix so that I can add all the files or the entire folder consisting the files at once? I am new to wix and i didnt find any option in any tutorial for this... Please do assist me and thanks in advance.....
Heat is the WiX harvest tool. You can run it on a directory to generate the necessary WiX source code.
EDIT:
If you want to run heat before your VS project builds, add it to your project prebuild events as seen in the screenshot below (this is how I have my project setup to dynamically generate WiX source for our ever changing help content):
Note the -var wix.HelpSource switch that I have. The WiX source files generated by heat will set the location of the source files to that variable instead of hard-coding it. So the generated source will have components that look something like this:
<Component Id="Welcome.htm" Directory="Content" Guid="INSERT-GUID-HERE">
<File Id="Welcome.htm" KeyPath="yes" Source="!(wix.HelpSource)\Content\Welcome.htm" />
</Component>
And in my particular case, I define that variable on the Tool Settings screen of my WiX VS project to the relative directory ..\..\Help\Output as seen below:
NOTE: Harvesting files in this manner will cause the GUIDs of the components harvested to change every time you build. If you don't want your GUIDs to change, you may have to write some wrapper that calls heat to harvest the files, then updates your original WiX source, leaving all the GUIDs alone.

Using heat.exe to add bulk files to a new WiX project: HEAT5150

If this is a repeat question, please direct me to the existing solution. I wasn't able to find a matching query.
We currently use InstallShield. I'm attempting to covert a project with 407 files to a WiX3 installation package. I tried using heat.exe to do some of the automation but I get the following warning for almost every file:
c:> heat dir "c:\projectDir\projectA" -gg -ke -template:Product -out "c:\install\projectA\heatOutput"
heat.exe: warning HEAT5150 : Could not harvest data from a file that was expected to be a SelfReg DLL: c:\projectDir\projectA\plugin1.dll. If this file does not support SelfReg you can ignore this warning. Otherwise, this error detail may be helpful to diagnose the failure: Unable to load file: c:\projectDir\projectA\plugin1.dll, error: 126.
Q: Is it normal for this warning to be reported for every file?
If there's a current "How To create/convert to your first WiX install project with many files" tutorial, please point me to it. The key requirement is "with many files".
PS. I know that WiX is designed for incremental install project creation but it would be nice to know if there's an automated way to convert existing install projects.
If there's a current "How To
create/convert to your first WiX
install project with many files"
tutorial, please point me to it. The
key requirement is "with many files"
You can take the msi file generated with installshield, and then decompile it with the dark.exe tool which comes with wix. As you can see in this diagram, dark.exe generates wxs files from a msi file.
You can use it like this:
dark installer.msi decompiled.wxs
See dark /? for more information.
edit: I don't use Votive, but AFAIK it should be able to handle the wxs files generated by dark. Did Votive show you an error?
edit2: wixproj files are just for visual studio and msbuild integration. The core tools don't know or use this format. Simply create a blank wixproj and add the wxs file to it from visual studio.
edit3: You should not compare the size of the wxs file to the msi file size. Like an installshield project file, a wxs does not contain the files to install. It only references them. Your installshield project file is not 70MB large either. If you want to extract the binary files from the MSI, then you should use dark.exe with the -x <path> switch.
Are you trying to extract data from x64 DLL's? That doesn't really work...