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.
Related
I managed to get TFS 2010 to create Web Deployment ZIPs (WebDeploy).
Now the issue is that I have multiple Web projects in the solution and packages are being created for all web projects.
In the projects that I do not want a package, I uncheck the "Create deployment package as a zip". I thought this will prevent MSBuild from creating a deployment package.
BTW I am passing "/p:DeployOnBuild=true" to MSBuild.
Is there a way to get MSBuild only package selected projects and not all Web projects?
Thanks.
Ok. Found the solution. Many thanks to Vishal Joshi for this post.
Extract from the post:
"
Deployment for Web Apps is feasible at both Solution as well as Project build level although when it comes to Solution Build then you might want to make sure that the properties you are passing at Solution level will apply to all the projects in the solution which might not always the outcome you desire. In that situation all these properties can be set within the .csproj or .vbproj files too. You can do that by unloading your project file and in the top <PropertyGroup> section just add above properties as you like:
For e.g /p:DeployOnBuild=True can be added as <DeployOnBuild>True</DeployOnBuild>
"
So, the solution was to remove /p:DeployOnBuild=true from TFS Build process template and update only the project files that require a package.
We current do manual builds/publish from Visual Studio 2010 and we require users to always be running the latest version (check before startup and minimum required version set). I am working on scripting our deployment out and have no issues using msbuild to build/publish. However, I have not found a way to auto-increment the minimum required version when msbuild runs. What are my options to automatically bump this when publishing via msbuild?
I did see quite a few articles on this topic here, but they seemed to be specific to VS and not MSBuild.
Updating the MinimumRequiredVersion Automatically
Introduction to Project Editor
In Solution Explorer, right click on your project and select unload project.
Once the project has become unavailable, right click again and select edit <project_name>.<lang> proj.
Introduction to MSBuild
Properties use key/value pairs to extract information
Using the property name as an alias, you can use $(OutputPath) to obtain the value for the element <OutputPath>.\bin</OutputPath>
We’ll use the following properties generated for a ClickOnce deployment
<MinimumRequiredVersion>1.0.0.6</MinimumRequiredVersion>
<ApplicationRevision>7</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
MSBuild Tasks can be specified in the project (*.proj) file and invoked during a build event.
FormatVersion is a built-in task for .NET 4.0 and later that formats the ApplicationVersion and ApplicationRevision into a single version number.
Implementation
Copy and Paste the following code into the opened project file as a child element to the root <Project> element.
<Target Name="AutoSetMinimumRequiredVersion" BeforeTargets="GenerateDeploymentManifest">
<FormatVersion Version="$(ApplicationVersion)" Revision="$(ApplicationRevision)">
<Output PropertyName="MinimumRequiredVersion" TaskParameter="OutputVersion" />
</FormatVersion>
<FormatVersion Version="$(ApplicationVersion)" Revision="$(ApplicationRevision)">
<Output PropertyName="_DeploymentBuiltMinimumRequiredVersion" TaskParameter="OutputVersion" />
</FormatVersion>
</Target>
This code will take ApplicationVersion and ApplicationRevision as parameters in the Format Version task and will save the output by overwriting the MinimumRequiredVersion with the full publish version.
Save and reload your project. Every ClickOnce deployment will now automatically update to the most recently published version.
Many thanks to Kev for their answer which I have basically rehashed here with a little bit of added clarification for any beginners. Here's a blog post I made about the issue that expands even more on my answer here.
Right now, I'm leaning towards updating the MinimumRequiredVersion via a custom command-line utility that will simply read in the project file and increment it. It's the only option I've come up with for scripting out my build.
I'm not sure if you're going about this the best possible way.
I would recommend using a continuous integration (CI) server like Team City that is responsible for deployments. If having the latest version of the source code is a requirement for publishing, then that is probably something you should build into a well-tested CI build configuration, and take away from the hands of the potentially forgetful/occasionally error-prone users.
Since you are wanting to publish using MSBuild and not Visual Studio, I assume you are publishing from a build server or using some sort of script. You can use the Set-ProjectFilesClickOnceVersion PowerShell script to both set the ClickOnce Application Version as well as force the Minimum Required Version to be the latest version. You would want to do this before running MSBuild. My blog describes in more detail how to setup your build server to accommodate publishing ClickOnce applications.
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.
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
I have taken over the development of a web application that is targeted at the .net 1.0 framework and is written in C# and Visual Basic.
I decided that the first thing we need to do is refine the build process, I wrote build files for the C# projects, but am having tons of problems creating a build file for Visual Basic.
Admittedly, I do not personally know VB, but it seems like I have to hardcode all the imports and references in my build file to get anything to work...certainly not the best way to be doing things...
For any example: if I do not include the namespace System in the build file I will get several errors of common Unkown Types e.g: Guid
does NAnt typically require this for VB code or is does the VB code need a possible NAnt-freindly refactoring?
Does anybody have VB NAnt tips?
I have had a similar experience with NAnt and the vbc compiler for VB.NET projects that are developed with Visual Studio. My solution has been to avoid importing namespaces at the project level in Visual Studio (which occurs by default), and use explicit Imports statements at the class/file level. C# projects work this way by default (no project level namespace imports), and I like the extra information provided by explicit namespace directives when looking at a file.
Interesting that VB.NET and C# VS projects are so different in that respect.
I'm not sure, if you talk about VB or VB.Net.
Either way, have a look at Nant Contrib. Maybe they have a solution.
Are you calling msbuild to build? Or are you calling the VS.NET IDE exe to build. We've had no problems with our c#/VB.NET mix using CC.NET and NAnt and do not have to specify referenced assemblies inside of the build files.
What we do is using the IDE exe to build solutions that contain the projects we want to build.
I would recommend that you take the language specific compilers out of the equation for this one. And you can still use NAnt to do this:
First start off with a target that uses MSBuild because that will compile your project regardless of language used and take care of the dependencies for you. That means you don't need to hard code them in.
Example:
<target name="WinBuild">
<exec program="msbuild.exe"
basedir="${DotNetPath}"
workingdir="${SolutionPath}"
commandline="MySolution.sln
/nologo /verbosity:normal /noconsolelogger
/p:Configuration=Debug /target:Rebuild" />
</target>
I think once you've got that nailed - you can spend plenty of time trying to get NAnt to compile natively, but in my opinion, this is what I would use for this project since it seems to be a once off?
Hope that helps,
Cheers,
Rob G