Very few .NET developers ever look at the XML inside their .csproj file or further understand how it all works. The good news is its not that difficult to understand. In this post we will see how you can create a custom project file for a Nuget package project.
The default ASP.NET csproj file has over 100 lines of MSBuild XML but this project will be much smaller. First we need to list the files that are part of the project so they are listed in the Visual Studio Solution Explorer by default. This is accomplished by adding the files to an ItemGroup named “None”. This group is for files that have a build action of “None”. For this Nuget package, we don’t need the files to be compiled.
<?xml version="1.0" encoding="utf-8"?> <Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup> <None Include="MSDeployAllTheThings.PublishingPipeline.nuspec" /> <None Include="nuget\tools\PublishingPipelineCore.targets" /> <None Include="nuget\tools\SlowCheetah.Transforms.targets" /> <None Include="nuget\tools\SlowCheetah.Tasks.dll" /> </ItemGroup> <Import Project="..\_build\BuildNugetPackage.targets" /> </Project>
To create the Nuget package we will call the Nuget.exe command. In this case I have refactored that build script into its own .targets file so I can reuse it for other projects as well. We reference the shared script in the solution folder using the Import node.
In the BuildNugetPackage.targets script we first import the nuget.targets file so we can download Nuget.exe. The .nuget folder is added by Visual Studio to aid in restoring Nuget packages. In our case, it conveniently provides a target for downloading Nuget.exe. Next we set the DownloadNuGetExe property to true. Then we set the build targets. The Rebuild target simply calls the Clean and Build targets. The Build target creates a package folder and execute Nuget.exe with the pack command to create our Nuget package. We also provide the .nuspec file which should share the same name as our VS project, set the output folder and the base path to our “nuget” folder. Lastly, the Clean target simply removes the “package” directory.
<?xml version="1.0" encoding="utf-8"?> <Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Import Project="..\.nuget\nuget.targets" /> <PropertyGroup> <DownloadNuGetExe Condition="'$(DownloadNuGetExe)'==''">true</DownloadNuGetExe> </PropertyGroup> <Target Name="ReBuild"> <CallTarget Targets="Clean" /> <CallTarget Targets="Build" /> </Target> <Target Name="Build"> <MakeDir Directories="package" /> <Exec Command="..\.nuget\nuget.exe pack $(MSBuildProjectName).nuspec -outputdirectory package -basePath nuget" /> </Target> <Target Name="Clean"> <RemoveDir Directories="package" /> </Target> </Project>
In this post you have seen how easy it can be to create a completely custom MSBuild project file. We use this approach on the MSBuildAllTheThings Nuget packages which you can review further, download to see a working example and try it for yourself.