MSBuild是什么?
MSBuild全稱(Microsoft Build Engine),是用於構建應用程序的平台。您可能不知道它,但是如果您在使用VS做開發,那么一定時時刻刻在使用它。因為是它在背后為你管理生成你的項目文件。當新建一個項目時,注意下項目文件夾中的*.*proj文件就是為MSBuild提供的,這是個文本文件,基於XML格式,里面包含有項目所包含的文件,生成配置,輸出配置等信息。當把一個文件或者圖片等添加到項目中,就會在這里添加一個描述,反之則刪除一個描述信息;在項目屬性頁所做的配置也會在這里存儲。
為何去了解MSBuild
想去了解這個源於以前學WPF時的疑惑(當時就想從MSBuild下手了,一直沒精力,拖到現在),因為不知道XAML為何就跑到生成的程序集,以及這個XAML標記最后變成什么,WPF是如何處理這些XAML標簽與C#代碼的?一般寫代碼時我都會清楚的知道這個代碼最后經由編譯器變成了什么,這樣心里比較底。但是這個XAML,是看不透,看不透就心里堵得慌,不踏實,我比較喜歡刨根問底,所以就想到通過這個入口探個究竟。
我想從MSBuild中得到什么
MSBuild基本概念
MSBuild有四個基本塊(屬性、項、任務、目標):
一句話總結MSBuild的作用:利用配置信息對項目文件實施特定順序的操作。
MSBuild屬性
屬性聲明方式:
1 <?xml version="1.0" encoding="utf-8"?> 2 <!--根元素,表示一個項目--> 3 <!--DefaultTargets用於定默認執行的目標--> 4 <Project DefaultTargets="build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 5 <!--屬性都要包含在PropertyGroup元素內部--> 6 <PropertyGroup> 7 <!--聲明一個"linianhui"屬性,其值為"hello world"--> 8 <linianhui>hello world</linianhui> 9 </PropertyGroup> 10 <!--目標--> 11 <Target Name="build"> 12 <!--MSBuild提供的一個內置任務,用於生成記錄信息用$(屬性名)來引用屬性的值--> 13 <Message Text="$(linianhui)"></Message> 14 </Target> 15 </Project>
保存此文件到d:\helloworld.xml文件。打開CMD窗口,輸入MSBuild helloworld.xml:

打印出“linianhui”屬性的值。MSBuild提供一些保留屬性,可以方便的引用$,如$(MSBuildProjectFile)將返回項目文件的完整名(helloworld.xml)。其他的保留屬性可以查閱MSDN幫助文檔。
MSBuild項
項聲明方式:
<?xml version="1.0" encoding="utf-8"?> <Project DefaultTargets="build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <!--項都要包含在ItemGroup元素內部--> <ItemGroup> <!--聲明一個"CSFile"的項,Include表示引入"csfile1.cs"文件--> <CSFile Include="csfile1.cs"> <!--Version表示項的元數據(附加信息)--> <Version>1.0.0.0</Version> </CSFile> <!--也可用";"一次引入多個文件--> <CSFile Include="csfile2.cs;csfile3.cs"/> </ItemGroup> <Target Name="build"> <!--@引用項的值,默認以";"分割開--> <!--輸出"csfile1.cs;csfile2.cs;csfile3.cs"--> <Message Text="@(CSFile)"></Message> <!--可以加第二個參數替換默認的";"分隔符--> <!--輸出"csfile1.cs+csfile2.cs+csfile3.cs"--> <Message Text="@(CSFile,'+')"></Message> <!--%引用項的元數據,輸出"1.0.0.0"--> <Message Text="%(CSFile.Version)"></Message> </Target> </Project>
MSBuild任務
上述Msaage就是一個任務,用於打印信息,常用的一些還包括CSC、MakeDir、Copy等等,大多任務都是有輸出信息的,這些信息可以通過OutPut元素存儲在屬性或者項中。先寫如下CS代碼:
1 //存為d:\MSBuildDemo.cs 2 public class MSBuildDemo 3 { 4 static void Main() 5 { 6 System.Console.WriteLine("MSBuild組織編譯"); 7 } 8 }
然后更改項目文件如下:
1 <?xml version="1.0" encoding="utf-8"?> 2 <Project DefaultTargets="build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 3 <ItemGroup> 4 <!--指定要編譯的文件--> 5 <CSFile Include="MSBuildDemo.cs"/> 6 </ItemGroup> 7 <Target Name="build"> 8 <!--使用Csc任務,對應csc編譯器--> 9 <!--Sources屬性表示要編譯的文件集合--> 10 <!--TargetType表示編譯目標類型,對應csc編譯器的/target參數--> 11 <Csc Sources="@(CSFile)" 12 TargetType="exe"> 13 <!--OutputAssembly為csc的輸出參數--> 14 <!--PropertyName表示把TaskParameter屬性所指定的輸出參數的值存儲到outputExeName這個屬性中--> 15 <!--Output還有一個ItemName屬性,表示存儲到一個項中--> 16 <Output TaskParameter="OutputAssembly" PropertyName="outputExeFileName"/> 17 </Csc> 18 <!--Message任務就可以使用csc所導出的屬性outputExeFileName了--> 19 <!--輸出MSBuildDemo.exe--> 20 <Message Text="$(outputExeFileName)"/> 21 <!--Exec任務可以運行帶有指定程序(可加參數)或命令--> 22 <!--運行剛從MSBuildDemo.cs源文件編譯好的程序--> 23 <!--運行結果為"MSBuild組織編譯"--> 24 <Exec Command="$(outputExeFileName)"></Exec> 25 </Target> 26 </Project>
用MSbuild執行此項目文件,如期正確打印信息。
MSBuild目標
上面的一個例子中Target元素就是MSBuild目標,此目標按照編譯源代碼、打印編譯好的程序文件名、執行該文件這個順序組織了這三個任務。這就是目標所要做的事情。先簡單介紹到這里吧,關於(屬性、項、任務、目標)的一些擴展信息會在下一篇介紹。如有錯誤之處,歡迎指正!
注:以上資料全部來自MSDN幫助文檔。https://docs.microsoft.com/zh-cn/visualstudio/msbuild/msbuild