This is a guide on how to create a MSBuild file that can be used to build your C#/.NET project in Visual Studio, without Visual Studio on Windows or with xbuild on mono in a single step.
Additionally, you can use NuGet packages and they will be automatically restored at build time.
There's also support for running unit tests.
Build file
If your solution is called Project.sln
, name your build file as Project.Build.msbuildproj
.
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<SolutionDir>$(MSBuildThisFileDirectory)</SolutionDir>
<Configuration Condition=" '$(Configuration)'=='' ">Release</Configuration>
<NuGetExe Condition=" '$(NuGetExe)'=='' ">packages/nuget.exe</NuGetExe>
<NuGetExeDir>packages/</NuGetExeDir>
<NuGetDownloadAddress Condition=" '$(NuGetDownloadAddress)'=='' ">http://nuget.org/nuget.exe</NuGetDownloadAddress>
<NuGetCommand Condition=" '$(NuGetCommand)'=='' AND '$(OS)' == 'Windows_NT'">"$(NuGetExe)"</NuGetCommand>
<NuGetCommand Condition=" '$(NuGetCommand)'=='' AND '$(OS)' != 'Windows_NT' ">mono --runtime=v4.0.30319 "$(NuGetExe)"</NuGetCommand>
<Properties>Configuration=$(Configuration);SolutionDir=$(SolutionDir)</Properties>
</PropertyGroup>
<ItemGroup>
<Solution Include="*.sln" />
<TestProjects Include="**\*.Tests.csproj" />
</ItemGroup>
<UsingTask TaskName="DownloadFile" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll" Condition=" '$(OS)' == 'Windows_NT' ">
<ParameterGroup>
<Address ParameterType="System.String" Required="true"/>
<OutputFilename ParameterType="System.String" Required="true" />
</ParameterGroup>
<Task>
<Reference Include="System" />
<Code Type="Fragment" Language="cs">
<![CDATA[
new System.Net.WebClient().DownloadFile(Address, OutputFilename);
]]>
</Code>
</Task>
</UsingTask>
<Target Name="DownloadNuGet">
<MakeDir Directories="$(NuGetExeDir)" Condition=" !Exists('$(NuGetExeDir)') " />
<DownloadFile Address="$(NuGetDownloadAddress)" OutputFilename="$(NuGetExe)" Condition=" '$(OS)' == 'Windows_NT' AND !Exists('$(NuGetExe)')" />
<Exec Command="wget $(NuGetDownloadAddress) -O $(NuGetExe)" Condition=" '$(OS)' != 'Windows_NT' AND !Exists('$(NuGetExe)') " />
</Target>
<Target Name="RestorePackages" DependsOnTargets="DownloadNuGet">
<Exec Command="$(NuGetCommand) restore "%(Solution.Identity)"" />
</Target>
<Target Name="Clean">
<MSBuild Targets="Clean" Projects="@(Solution)" Properties="$(Properties)" />
</Target>
<Target Name="Build" DependsOnTargets="RestorePackages">
<MSBuild Targets="Build" Projects="@(Solution)" Properties="$(Properties)" />
</Target>
<Target Name="Rebuild" DependsOnTargets="RestorePackages">
<MSBuild Targets="Rebuild" Projects="@(Solution)" Properties="$(Properties)" />
</Target>
<Target Name="RunTests" DependsOnTargets="Build">
<MSBuild Targets="RunTests" Projects="@(TestProjects)" Properties="$(Properties)" />
</Target>
</Project>
This will build your solutions (*.sln
) restoring NuGet packages beforehand (also downloading nuget.exe
if necessary using .NET on Windows and wget
on Linux). You can also clean, rebuild or just restore packages. If you have any projects with .Tests
in the name, there's target for running tests.
Building
On Windows with MSBuild
By default MSBuild.exe
is located at C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe
and it's not in your PATH
by default.
msbuild Project.Build.msbuildproj
On Linux with mono and xbuild
You will need to have the latest mono and xbuild packages installed.
xbuild Project.Build.msbuildproj
Visual Studio
You don't need Project.Build.msbuildproj
in Visual Studio since it's just a wrapper. Newest versions of Visual Studio can automatically restore NuGet packages. But you can launch it from Visual Studio as an External Tool. Go to Tools -> External Tools and add MSBuild.exe
with Project.Build.msbuildproj
as a parameter. You can then launch it from the
Parameters
Parameters for msbuild
and xbuild
are the same.
Clean your project
msbuild Project.Build.msbuildproj /t:Clean
Build in Debug
configuration
msbuild Project.Build.msbuildproj /p:Configuration=Debug
Restore NuGet packages only
msbuild Project.Build.msbuildproj /t:RestorePackages
Override variables
msbuild Project.Build.msbuildproj /p:NuGetExe=".nuget/nuget.exe"