MSBuild位置

C:\Windows\Microsoft.NET\Framework64\v4.0.30319

MSBuild

MSBuild 是 Microsoft 和 Visual Studio的生成系统。它不仅仅是一个构造工具,应该称之为拥有相当强大扩展能力的自动化平台。MSBuild平台的主要涉及到三部分:执行引擎、构造工程、任务。其中最核心的就是执行引擎,它包括定义构造工程的规范,解释构造工程,执行“构造动作”;构造工程是用来描述构造任务的,大多数情况下我们使用MSBuild就是遵循规范,编写一个构造工程;MSBuild引擎执行的每一个“构造动作”就是通过任务实现的,任务就是MSBuild的扩展机制,通过编写新的任务就能够不断扩充MSBuild的执行能力。所以这三部分分别代表了引擎、脚本和扩展能力。

MSBuild示例

//msbuild helloworld.xml

<?xml version="1.0" encoding="utf-8"?>
<!--根元素,表示一个项目-->
<!--DefaultTargets用于定默认执行的目标-->
<Project DefaultTargets="build;output" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
	<!--属性都要包含在PropertyGroup元素内部-->
	<PropertyGroup>
		<!--声明一个"word"属性,其值为"hello world"-->
		<word>hello world</word>
	</PropertyGroup>
	<!--目标-->
	<Target Name="build">
		<!--MSBuild提供的一个内置任务,用于生成记录信息用$(属性名)来引用属性的值-->
		<Message Text="my first MSBuild $(word)"/>
	</Target>
	<Target Name="output">
		<Message Text="target output"/>
	</Target>
</Project>

PropertyGroup

属性是可用于配置生成的名称/值对。使用语法$(word)获取该属性值。属性值可通过重新定义属性进行更改。属性按其在项目中的显示顺序进行评估。MSBuild保留了一些属性名称,环境变量也会作为属性自动导入到MSBuild中,方法与引用保留属性相同。例如,若要使用项目文件中的 PATH 环境变量,可使用 $(Path)。 如果项目包含与环境属性具有相同名称的属性定义,则项目中的属性将覆盖环境变量的值。还可以使用$(registry:Hive\MyKey\MySubKey@Value)获取注册表属性。可使用 -property (或 -p )开关在命令行中设置属性。 这些全局属性值会覆盖项目文件中设置的属性值。 这包括环境属性,但不包括不能更改的保留属性。

	<PropertyGroup>
		<!--声明一个"word"属性,其值为"hello world"-->
		<word>hello world</word>
	</PropertyGroup>

msbuild.exe MyProj.proj -p:Configuration=DEBUG

//属性函数
<Today>$([System.DateTime]::Now.ToString("yyyy.MM.dd"))</Today>

//任何任务都可以发出属性。 若要发出属性,Task 元素必须具有含有 PropertyName 属性的 Output 子元素。
<Target Name="build">
	<!--使用Csc任务,对应csc编译器-->
	<!--Sources属性表示要编译的文件集合-->
	<!--TargetType表示编译目标类型,对应csc编译器的/target参数-->
	<Csc Sources="@(CSFile)" TargetType="exe">
		<!--OutputAssembly为csc的输出参数-->
		<!--PropertyName表示把TaskParameter属性所指定的输出参数的值存储到outputExeName这个属性中-->
		<!--Output还有一个ItemName属性,表示存储到一个项中-->
		<Output TaskParameter="OutputAssembly" PropertyName="outputExeFileName"/>
	</Csc>
	<!--Message任务就可以使用csc所导出的属性outputExeFileName了-->
	<!--输出FirstCS.exe-->
	<Message Text="$(outputExeFileName)"/>
	<!--Exec任务可以运行带有指定程序(可加参数)或命令-->
	<!--运行刚从FirstCS.cs源文件编译好的程序-->
	<!--运行结果为"MSBuild组织编译"-->
	<Exec Command="$(outputExeFileName)"/>
</Target>

ItemGroup

MSBuild 项是生成系统的输入,通常表示文件(文件在 Include 属性中指定)。 根据项元素名称,将其组成不同的项类型。 项类型是项的命名列表,可用作任务参数。 任务使用项值来执行生成过程。使用@(CSFile)访问。

<ItemGroup>
	<!--声明一个"CSFile"的项,Include表示引入"FirstCS.cs"文件-->
	<CSFile Include="FirstCS.cs">
		<!--Version表示项的元数据(附加信息)-->
		<Version>2.0.0.0</Version>
	</CSFile>
	<!--也可用";"一次引入多个文件-->
	<CSFile Include="SecondCS.cs;ThirdCS.cs"/>
</ItemGroup>

//使用通配符
<CSFile Include="*.cs"/>

//项元素可包含 Exclude 属性,该属性用于从项类型中排除特定项(文件)
<ItemGroup>
    <CSFile  Include="*.cs"  Exclude="DoNotBuild.cs"/>
</ItemGroup>

项元数据

可使用语法 %(),在整个项目中引用项元数据。 如果存在不明确性,则可使用项类型的名称来限定引用。 例如,可指定 %()。

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <ItemGroup>
        <Stuff Include="One.cs" >
            <Display>false</Display>
        </Stuff>
        <Stuff Include="Two.cs">
            <Display>true</Display>
        </Stuff>
    </ItemGroup>
    <Target Name="Batching">
        <Message Text="@(Stuff)" Condition=" '%(Display)' == 'true' "/>
    </Target>
</Project>

DefaultTargets

通过设置Project的DefaultTargets(注意是复数)属性来指定需要运行哪(几)个Target,如果没有这个设置,MSBuild将只运行排在最前面的那个Target。

DependsOnTargets

设置Target的DependsOnTargets属性(注意是复数),以表示仅当这些Target执行完成之后才能执行当前的Target。当MSBuild引擎开始执行某项Target时(别忘了Project的DefaultTargets属性),会自动检测它所依赖的那些Target是否已经执行完成,从而避免因为某个生成环节缺失而导致整个生成过程发生意外。

Message

Message中可以用于在Target中输出字符串。

	<Target Name="output">
		<Message Text="target output"/>
	</Target>

TargetFrameworks & TargetFramework

Use the TargetFrameworks property when you want your app to target multiple platforms. For a list of valid target framework monikers。

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>

<PropertyGroup>
<TargetFrameworks>net8.0;net462</TargetFrameworks>
</PropertyGroup>