Visual Studio and MSBuild fire BeforeBuild differently on a WiX project - msbuild

I have a WiX (Windows installer XML) v3, project which contains references to other projects in my solution. I am using the copy task inside the BeforeBuild event of the WiX project to collect some of the output of the references projects for later use my Heat.
When I build the WiX project (not the solution) inside Visual Studio, each of the referenced projects is build before my WiX project and once they are built, the BeforeBuild event on my WiX project fires and then the WiX project itself is built. This is the behaviour I expect - I am able to access files from the bin directories of the references projects in the WiX BeforeBuild and use them as I please before the WiX project executes Candle.
The problem I am having is when I build the WiX file via MSBuild I am finding that the BeforeBuild event fires straight away BEFORE any of the referenced projects. This difference in behaviour means that I cannot make use of the outputs of the referenced projects when building from the command line.
Why is BeforeBuild executing at a different point in time when run via MSBuild on the command line to inside Visual Studio?

If you are building inside Visual Studio, the solution dependencies (which can be explicit or based on the project references) are used to determine which projects need to be built and a separate build is kicked off for each of them. This is necessary since solutions can also contain projects that are not built using MSBuild and other projects have explicit dependencies set in the solution for them. The side effect is that each project is treated as a stand-alone build, thus ensuring the right BeforeBuild order for you..
If you are building from the command line using MSBuild, the dependency projects are resolved (and built if necessary) during the ResolveReferences target. The BeforeBuild target and PreBuild event (executed from the PreBuildEvent target) are both performed before the ResolveReferences target. Thus the dependent project BeforeBuild target ends up executing before the build for the dependency project is kicked off.
Note that from a point of view of a single project, BeforeBuild target does make sense to be executed before resolving dependencies, as the dependency resolution might itself depend on the BeforeBuild target output. For example, BeforeBuild might execute a custom script to get the latest copy of any dependency projects from the SCM.

Related

How to Pass Different Build Arguments to Projects of one Solution

Background: We've got a single .NET solution which contains multiple projects, some of them are compiled against the .NET Framework, some against .NET Core (UWP). We use Visual Studio Team Services (was Visual Studio Online) to build our solution continuously.
Challenge: The UWP projects require different MSBuild arguments and platform settings. We created a build definition as per screenshot below: the solution is built first using the .NET arguments. Then, for every UWP project, we have an MSBuild step.
Problem: Every time we add, remove, or rename a UWP project we have to update the build definition. We would like to somehow select the UWP projects automatically, ideally using a Visual Studio Build Step and no custom scripting. Any ideas?
Working alternative: Originally, we split the solution into two (one solution per platform) and had two different Visual Studio Build events running against each solution. We prefer to work in one single solution though.
There isn't any easy way to achieve this without custom script.
You may trying creating a MSBuild project file and add your projects in it with separate arguments like following:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="Build">
<MSBuild Projects="Project1.csproj" Properties=Arguments1/>
<MSBuild Projects="Project2.csproj" Properties=Arguments2/>
</Target>
</Project>
Then you just need to build the project file in your build definition. But this will require you to update the MSProject file when you have project added/changed.
The Msbuild step supports wildcards, so you could set it to build **/*.uwp.csproj if your projects follow this naming pattern.

Referencing WiX extension in same solution as wixproj

I wrote up a quick WiX preprocessor extension to grab some product version information from a file we keep in our root folder.
I'd like to keep this extension in the same solution as our WiX setup project, because it's easier to maintain. But the problem is that when testing, we use a Debug configuration, and when releasing a build, we switch to Release. This means that I have two extensions to deal with.
How would I tell WiX to grab one depending on the current configuration?
I've been looking at the reference paths in the WiX project's properties, and added "..\MyWiXExtensions\bin\$(Configuration)\" as a folder, hoping that it would pick up the MSBuild property, but that doesn't seem to work.
I've also looked at the build events. I could copy the output dll to my setup project's folder, but wouldn't that break references if I clean my solution?
I'm using WiX 3.7 and Visual Studio 2012.
I ended up using a post-build event on my extension that would copy the output to my wixproj's folder.
I just have to build my wixproj separately from the rest of the solution to prevent file locking issues when overwriting the dll. If file locking does come up, I just have to close VS and reopen the solution.
As a side note, referencing the project itself instead of the dll could be a nice feature to have in Votive.

Difference between MSBuild with DeployOnBuild and Visual Studio Publish

I have an WCF project that if i use the Visual Studio option "Publish" gets published fine.
But if I use the MSBuild parameter DeployOnBuild it does not get published correctly. I'm getting an "Could not load type" error, and all of de dlls are there.
I using the MSBuild in a Build Definition in order to have a Continuous Integration Build.
The build parameters I'm using are:
/p:DeployOnBuild=true
/p:DeployTarget=MSDeployPublish
/p:MSDeployPublishMethod=RemoteAgent
/p:MsDeployServiceUrl=http://host/msdeployagentservice
/p:username=#####
/p:password=****
My main problem with this scenario is that the build targets are the same, and the build definition actualy publishes the files, but somehow they are not the same.
Any insights ???
I dont like to answer my on question, but since it may help someone else is the cause of the problem.
One of the projects had a post-build command to copy the resulting
dll to another project specific directory (its not a reference
because it using dependency injection in runtime).
The dlls did not get checked in to TFS because they are not checkout automaticaly
The
Continuous Integration Build fetches the sources from TFS and the dlls are out of sync
The solution was to checkout the dlls before the build so that the checkin updates them

How do you make a WiX project build when dependent files have changes?

I've adopted a Visual Studio solution that contains a number WiX projects. We build the solution from an MsBuild script to generate the product's installer msi.
The problem I'm experiencing is that if I build (and don't rebuild), even if exe's and dll's get updated that need to be put in the installer, the WiX build system doesn't seem to detect this and skips building the installer as it thinks it's already up to date.
How do I work out what the dependencies are that are needed to build a WiX project, and how do I tell the Wix build system to watch out for them changing so it knows to build instead of skip?
Thanks.
This facility was added to WiX 3.6 with little fanfare - in the WiX 3.6 release notes it simply says ".wixproj MSBuild projects support incremental build."
The WiX MSBuild targets don't currently support payloads as inputs into the build process, so nothing tells MSBuild that the WiX targets need to be called. Feel free to file a feature request at wix.sf.net; a couple of us have been talking about ways to do it.
If you can include the projects that create the exe's and dll's into the solution containing the wix projects, you can add project references from the wix projects to the appropriate application projects. Then wix should properly perform incremental builds.
I configure my wix projects to only be included in the release configuration so that the apps can be quickly built and run without creating the install in the debug configuration.

Is it possible from within the csproj file to know whether devenv or msbuild is used to run it?

Motivation:
I have fxcop integrated in the build process, which makes fxcopcmd.exe run each time the target has changed or as long as there are warnings from the previous run of fxcop.
But when one works in the studio, devenv.exe often decides to compile the project in background for whatever reasons. For example, when I add a new project to the solution I notice that fxcopcmd.exe runs, meaning a background build has started. There are also other times as well.
So, I wish to suppress fxcop when built with devenv. Our CI server builds using msbuild, so no problem there.
BTW, if there is a way to disable the background builds, that could be great.
There is a property BuildingInsideVisualStudio which will tell you this.
For example compare the result when using msbuild.exe and devenv.exe with a .csproj with the following AfterBuild target defined
<Target Name="AfterBuild">
<Message Text="BuildingInsideVisualStudio: $(BuildingInsideVisualStudio)" Importance="high"/>
</Target>
Sayed Ibrahim Hashimi
My Book: Inside the Microsoft Build Engine : Using MSBuild and Team Foundation Build
The only thing I can think of is to either
create a different build type (such as debug_and_rules, release_and_rules, etc). I think ms build could read this.
have your CI server call the fxcop exe separate from building the project. This is what I used to do before fxcop was integrated into VS.
have msbuild set a setting or compiler flag that ms build could read. I'm not sure if this would work.
The background compiler was added in VS 2008 to C#, and as far as I know, is not configurable. VS 2010 is supposed to be ultra configurable so maybe that will change
Edit: formatted my list a little better