Originally published on 2016-07-02; fully revised and updated.
MSBuild separates build logic into different file types so teams can reuse settings, tasks, and targets across many projects. If you work with .NET builds, this guide clarifies the role of each extension, shows how imports are typically layered, and provides practical examples you can adapt. This revision is based on the original post.

What each MSBuild-related extension is for
| Extension or pattern | Primary purpose | Typical usage | Example |
|---|---|---|---|
.proj | Top-level or orchestrator build project | Calls targets, imports shared files, coordinates multi-project builds | build.proj, main.proj |
.targets | Reusable target definitions | Imported into other projects; usually provides build steps, not full standalone builds | Microsoft.Common.targets |
.props | Shared properties and defaults | Imported early to set common values used later in evaluation | Microsoft.Cpp.props |
.tasks | Task registration includes | Contains UsingTask declarations for custom tasks | MSBuild.ExtensionPack.tasks |
.settings.targets | Team naming convention for shared settings | Imported file for common build and deployment settings | EntityFramework.settings.targets |
*proj | Language or project-type file | Main project definition consumed by MSBuild tooling | .csproj, .vbproj, .vcxproj |
Language-specific project extensions from the original reference
The original article also listed these project-type extensions. They identify the language or tooling ecosystem around a project file.
| Extension | Project type |
|---|---|
.csproj | C# |
.vbproj | VB.NET |
.vcxproj | Visual C++ |
.dbproj | Database project |
.fsproj | F# |
.pyproj | IronPython |
.rbproj | IronRuby |
.wixproj | Windows Installer XML (WiX) |
.vdproj | Visual Studio Deployment Project |
.isproj | InstallShield |
.pssproj | PowerShell |
.modelproj | Modeling project |
How these files typically work together
Import order and file responsibility are the core ideas: shared properties are usually loaded early, reusable targets and tasks are imported where needed, and the entry project triggers execution.
flowchart LR
A[Start build command] --> B[Load entry project file]
B --> C[Import shared props]
C --> D[Evaluate properties and items]
D --> E[Import tasks and targets]
E --> F[Execute requested target]
F --> G[Compile package deploy]
Practical examples
Example: orchestrator .proj file that imports shared configuration and runs a project build.
<Project DefaultTargets='Build' xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
<Import Project='build/common.props' />
<Import Project='build/common.tasks' />
<Target Name='Build'>
<MSBuild Projects='src/MyApp/MyApp.csproj'
Targets='Build'
Properties='Configuration=Release' />
</Target>
<Import Project='build/common.targets' />
</Project>Code language: HTML, XML (xml)
Example: reusable .targets file.
<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
<Target Name='PrintBuildInfo' BeforeTargets='Build'>
<Message Text='Building $(MSBuildProjectName) in $(Configuration)'
Importance='high' />
</Target>
</Project>Code language: HTML, XML (xml)
Example: .tasks include containing task registrations.
<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
<UsingTask TaskName='Company.Build.ZipDirectory'
AssemblyFile='tools/Company.Build.Tasks.dll' />
</Project>Code language: HTML, XML (xml)
Common commands:
msbuild build.proj /t:Build /p:Configuration=Release
dotnet build src/MyApp/MyApp.csproj -c Release
About the .settings.targets convention
.settings.targets is a naming convention, not a special parser rule in MSBuild. In the original post, it is attributed to Sayed Ibrahim Hashimi (2009) as a way to centralize shared utility and deployment-related properties.
Best practices
- Keep
.projfiles focused on orchestration, not deep reusable logic. - Put reusable defaults in
.propsand reusable build actions in.targets. - Use
.tasks(or equivalent imported files) to isolate custom task registration. - Standardize naming so teams can quickly identify purpose from filename alone.
- Document import order explicitly, because MSBuild behavior is strongly order-dependent.
I’m Rajesh Kumar, a DevOps, SRE, DevSecOps, Cloud, and Platform Engineering expert passionate about sharing practical knowledge, real-world experiences, and industry best practices. I have worked at Cotocus and regularly write about technology, travel, investing, health, product reviews, and digital marketing through my various platforms.
I publish technical articles at DevOps School, travel stories at Holiday Landmark, stock market insights at Stocks Mantra, health and fitness guidance at My Medic Plus, product reviews at TrueReviewNow, and SEO and digital marketing strategies at Wizbrand.
Find Trusted Cardiac Hospitals
Compare heart hospitals by city and services — all in one place.
Explore Hospitals