4

I'm trying to create a Wix installer for our app. Wix Project harvest does not work since it only copies the main exe file to the install dir, all dll's etc are not copied.

So I was thinking of having a pre build event that builds the app and use that output from Wix.

The problem is that the output will have files like .pdb, vchost.exe etc. Can I configure the build so that it only outputs the needed files?

edit: Final solution can be found here https://github.com/AndersMalmgren/FreePIE/blob/master/BuildTools

Start by looking in https://github.com/AndersMalmgren/FreePIE/blob/master/BuildTools/build_installer.bat

Anders
  • 17,306
  • 10
  • 76
  • 144

1 Answers1

7

When I create any type of installer/zip file/whatever for my projects, I never do that in the "standard" build in Visual Studio, i.e. in the .csproj file.
(I understand that's where you are trying to put the pre build event - correct?)
The reason is that I don't want to rebuild the installer/zip on every single build that I do while I'm programming.

What I always do:
I create a MSBuild project file that I can execute manually from the explorer (usually via batch file), which compiles the Visual Studio solution and then creates zip files, installers, NuGet packages or whatever I need.
So creating the setup is completely out of the Visual Studio solution, but I can pull the latest changes from source control and then build everything and create the setup with one single click.
(Joel Test, second question: "Can you make a build in one step?")

When I don't need everything that Visual Studio puts into the output folder, I just copy the files I need to a different folder first.

Here is an example from one of my projects:

  1. The MSBuild file
    The last paragraph ("copy files to release folder") copies the content of the \bin\Release folder (but excluding *.pdb and *.xml files) and some files from the root folder to a separate "release" directory:

     <!-- copy files to release folder -->
     <Target Name="CopyRelease">
             <MakeDir Directories="$(ReleaseDir)"/>
             <ItemGroup>
                     <ReleaseFiles
                             Include="$(OutDir)\**\*.*;
                                     README.md;
                                     License.rtf"
                             Exclude="$(OutDir)\*.pdb;
                                     $(OutDir)\*.xml">
                     </ReleaseFiles>
             </ItemGroup>
             <Copy SourceFiles="@(ReleaseFiles)" DestinationFiles="@(ReleaseFiles -> '$(ReleaseDir)\%(RecursiveDir)%(Filename)%(Extension)')"/>
    
     </Target>
    
  2. The batch file that I use to execute the MSBuild file
    There is more code in the batch file (to take care of stuff like version numbers), but the important part where I execute the MSBuild file is this:

     rem path to msbuild.exe
     path=%path%;%windir%\Microsoft.net\Framework\v4.0.30319
    
     rem go to current folder
     cd %~dp0
    
     msbuild build.proj
    

I'm actually using WiX to build the installer for this project, but I don't use the "harvest" feature that you are using (I didn't know about it before).
I just specify every single file for the installer in the WiX project file, and then I use another batch file to build the project (by calling the first batch file mentioned above) and then the WiX setup.

Even if my usage of the actual WiX tool is different than yours, you could still use a similar approach like the one explained above to create the "source folder" for WiX's harvest feature:
Call a batch file that copies exactly the files you need to a different folder, and use that as the source to create the installer.
If you don't want to create a MSBuild file, you can even use something like Robocopy (which is able to mirror a complete folder, but exclude certain file extensions).


EDIT:

  1. Try to build your complete solution, instead of just one project.
    Put a batch file with the following content in the folder where your .sln file is:

     set PATH=%PATH%;%WINDIR%\Microsoft.Net\Framework64\v4.0.30319
    
     rem go to current folder
     cd %~dp0
    
     msbuild YourSolution.sln /p:Configuration=Release
    
  2. The second error says something about a PreBuildEvent target
    --> Did you already put something into the pre build event of your .csproj? Maybe that doesn't work.


EDIT2:

I'm doing something similar:
I just have a batch file that puts the version number (which is hardcoded in my case) into an environment variable, and I call that batch file from my main build batch before doing the actual build.
In my .csproj, I have a pre-build event that sets the assembly version number to the value from the environment variable if it exists, otherwise just to 0.0.
(I don't care about the version number when I build from Visual Studio - I create all release builds with the batch file, so I only need the version number there)


EDIT 3:

Last step, get the entire output into Wix, you link each file, thats not practicle in mu project. its several sub folders, and thousand of files. Any good idea on how to link the entire output folder in wix?

Sorry, I never tried this before. The right way using WiX would have been to build the setup incrementally right from the beginning.

Quote from the link (emphasis by me):

Typing all those hundreds or thousands of components into the WiX source file presents another challenge, of course. The toolset has a small utility that can help with this (more about it later) but the real solution is a conceptual change. Stop considering the setup program as a separate application that has to be written in a rush when the main application is already finished. As the WiX source files and the toolset itself can be integrated into your development environment easily, you should keep them in sync all the time. As soon as you start working on a new module or add a new registry reference to your program, modify the corresponding WiX source file at the same time. This way, the setup will be finished together with the application itself and there will be no need to extract all the file and other pieces of information required for the installation later. As the WiX project can be modularized (more about this later), this approach works just as well if you have a large team working on the application rather than a single developer.

The link in the quoted text points to a page describing the Heat tool, which seems to be the "harvest" tool that you mentioned before and already tried without success.

Christian Specht
  • 35,843
  • 15
  • 128
  • 182
  • Thanks will probably go this route, maybe you can help me with something related. Im trying to build the projector with a bat file. See edit please – Anders Feb 10 '13 at 12:08
  • @Anders: I can't compile your complete solution, because I only have C# Express on this machine and you're using MSTest, which C# Express doesn't support. But with the batch file I suggested above, everything else except the test projects **does** compile...I just get lots of errors for the test projects. – Christian Specht Feb 10 '13 at 12:54
  • I found the problem, we use a msbuild script to extract the version number from Git. That msbuild script is then triggered from the pre buld event (This is so that you can build from within VS). That prebuild event does not play well with msbuild. Can I disable build events for mnsbuild? – Anders Feb 10 '13 at 13:04
  • http://stackoverflow.com/questions/1731904/can-you-prevent-msbuild-exe-from-running-build-events – Anders Feb 10 '13 at 13:06
  • Last step, get the entire output into Wix, you link each file, thats not practicle in mu project. its several sub folders, and thousand of files. Any good idea on how to link the entire output folder in wix? – Anders Feb 10 '13 at 14:45
  • I used Heat for the last step, worked but the docs are crap.. I will add a full edit with all the steps when I'm done – Anders Feb 10 '13 at 22:15
  • I updated my question with how I did it, thanks for the support! – Anders Feb 11 '13 at 01:15
  • btw, about your comment about that the Installer should grow together with the project. In our case there is two reasons for this not to work, One we migrated from VS2010 Project Setup and number two, we have large file database in this project, thousands of python files in this case. For these type of scenarios Heat works pretty well, but its very undocumented. I'm also a true believer of convention over configuration. – Anders Feb 11 '13 at 14:03