国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > 綜合 > 正文

MSBuild入門

2024-07-21 02:17:15
字體:
來源:轉載
供稿:網友
  • 本文來源于網頁設計愛好者web開發社區http://www.html.org.cn收集整理,歡迎訪問。
  • 如果你和我一樣一直都在用nant管理生成過程的話,那么你一定會高度關注msbuild。原因很簡單,因為它屬于微軟,你可以不喜歡它,但你一定要學會用它。



    在熬過了幾個晚上以后,我終于讓自己適應了msbuild的語法。這可真不容易,特別是當自己已經習慣了nant的小寫規范之后。不過這不成問題,因為隨著自己對msbuild的理解一點點加深,自己還真的喜歡上它了。



    好吧,下面就讓我來簡單地介紹一下我在學習msbuild使用過程中的一點經驗。如果你還在msbuild的大門外徘徊,那么希望這篇東西能帶你進入那扇門。



    準備工作

    首先要提到的是有關如何使用msbuild的一些重要資源。它們是:



    1. alex kipman的msdntv show:

    http://msdn.microsoft.com/msdntv/episode.aspx?xml=episodes/en/20040122vsnetak/manifest.xml

    2. alex kipman和rajeev goel在pdc2003上的演講:

    http://microsoft.sitestream.com/pdc2003/tls/tls347.htm

    上面這兩項出自msbuild開發組的alex kipman,從理論上說他應該是了解msbuild的第一人,他給出的幾個演示的確給了我非常大的幫助。(不過我非常不喜歡他的聲音,又尖又細。)



    3. msbuild doc

    http://msdn.microsoft.com/longhorn/toolsamp/default.aspx

    這是最重要的,其中包括alex kipman主筆的五份重要文檔:msbuildfileformat、msbuildwalkthrough、msbuildtasks、howtowriteatask以及msbuildcommandline。這可能是目前情況下外界能獲得的有關msbuild最詳細的文檔。





    demo

    好了,一切準備工作就緒,讓我們以一個簡單的示例開始吧。



    首先寫一個簡單的c# console程序(你也可以把它改成vb.net):



    // hellomsbuild.cs

    using system;



    class hellomsbuild

    {

    public static void main()

    {

    console.writeline("hello msbuild!");

    }

    }



    下面我們就要寫一個.csproj文件來控制整個生成過程。值得注意的是,如果在調用msbuild.exe時沒有指定具體的項目文件,msbuild引擎會在當前目錄下查找一個名為*.*proj的項目文件。如果你在同一目錄中寫了多個這樣的項目文件,那么需要手動指定msbuild.exe的目標文件,方法是:



    msbuild a.csproj



    否則msbuild會提示出錯,要求你手動指定目標項目文件。



    以下是項目文件:



    <!-- build.csproj -->

    <project defaulttargets="run">



    <property bin="bin" />

    <property outputassembly="hellomsbuild" />



    <item type="source" include="hellomsbuild.cs" />



    <target name="build">

    <task name="makedir"

    directories="$(bin)"

    condition="!exists('$(bin)')" />

    <task name="csc"

    sources="@(source)"

    targettype="exe"

    outputassembly="$(bin)/$(outputassembly).exe" />

    </target>



    <target name="run" dependsontargets="build">

    <task name="exec"

    command="$(bin)/$(outputassembly).exe" />

    </target>

    </project>



    如果你此前沒有過nant的開發經驗,那么上面這些東西肯定看起來挺嚇人。這個時候最好的辦法是打開那篇msbuildfileformat,對照上面代碼查找相應的項目元素的含義。下面我對其中重要的項目元素進行一下解釋。



    1. project元素。這是每一個項目文件的最外層元素,它表示了一個項目的范圍。如果缺少了這一元素,msbuild會報錯稱target元素無法識別或不被支持。



    project元素擁有多個屬性,其中最常用到的是defaulttargets屬性。我們都知道,在一個項目的生成過程中可能需要完成幾項不同的任務(比如編譯、單元測試、check-in到源代碼控制服務器中等),其中每一項任務都可以用target來表示。對于擁有多個target的項目,你可以通過設置project的defaulttargets(注意是復數)屬性來指定需要運行哪(幾)個target,比如:



    <project defaulttargets=”build” >

    ...



    或者:



    <project defaulttargets=”build;test;run” >

    ...



    如果沒有這個設置,msbuild將只運行排在最前面的那個target。



    2. property元素。在項目中你肯定需要經常訪問一些信息,例如需要創建的路徑名、最終生成的程序集名稱等。這些信息你最好別hard code進項目中,除非你一次寫過之后永不更改。這時property就能派上用場了。你把上面提到的那些信息以name/value的形式添加進property,隨后就可以以$(propertyname)的形式訪問。這樣你就無須為了改動一個文件名稱而讓整個項目文件傷筋動骨了。比如上面代碼中的bin就是將要創建的路徑名稱,而assemblyname則是最終要生成的程序集名稱。這些屬性的名稱不是固定的,你完全可以按自己的習慣來進行命名。在使用時,你需要把屬性名稱放在”$(“和”)”對內(不包括引號),以表示這里將被替換成一個property元素的值。



    另外,如果property元素數量比較多,你還可以把它們分門別類地放在不同的propertygroup里,以提高代碼的可閱讀性。這對property本身沒有任何影響。比如:



    <propertygroup>

    <property ... />

    <property ... />

    </propertygroup>



    3. item元素。在整個項目文件中你肯定要提供一些可被引用的輸入性資源(inputs)信息,比如源代碼文件、引用的程序集名稱、需要嵌入的圖標資源等。它們應該被放在item里,以便隨時引用。語法是:



    <item type=”thetype” include=”nameorpath” />



    其中type屬性可以被看作是資源的類別名稱,比如對于.cs源文件,你可以把它們的type都設置為source,對于引用的程序集把type都設置為reference,這樣在隨后想引用這一類別的資源時只要引用這個type就可以了,方法是@(typename)。可千萬別和property的引用方法弄混了。



    既然type是資源的類名,那么include就是具體的資源名稱了,比如在上面的示例代碼中,include引用的就是c#源代碼文件的名稱。你也可以用使用通配符*來擴大引用范圍。比如下面這行代碼就指定了當前目錄下的所有c#文件都可以通過@(source)來引用:



    <item type=”source” include=”*.cs” />



    另外,你也可以通過與propertygroup類似的方法把相關的item放在itemgroup里。



    4. target元素。上面已經提到了,target表示一個需要完成的虛擬的任務單元。每個project可以包括一個或多個target,從而完成一系列定制的任務。你需要給每個target設置一個name屬性(同一project下的兩個target不能擁有同樣的name)以便引用和區別。



    舉例來說,在你的項目生成過程中可能需要完成三個階段的任務:首先從vss中check-out源代碼,接下來編譯這些代碼并執行單元測試,最后把它們check-in回vss。那么通常情況下你可以創建三個不同的target以清晰劃分三個不同的階段:



    <target name=”checkout” >

    ...

    </target>



    <target name=”build” dependsontargets=”checkout”>

    <task name=”build” .../>

    <task name=”unittest” ... />

    </target>



    <target name=”checkin” dependsontargets=”checkout;build”>

    ...

    </target>



    這樣,你就可以非常清晰地控制整個生成過程。為了反應不同target之間的依賴關系(只有check-in后才能編譯,只有編譯完成才可能check-out……),你需要設置target的dependsontargets屬性(注意是復數),以表示僅當這些target執行完成之后才能執行當前的target。當msbuild引擎開始執行某項target時(別忘了project的defaulttargets屬性),會自動檢測它所依賴的那些target是否已經執行完成,從而避免因為某個生成環節缺失而導致整個生成過程發生意外。



    你可以通過project的defaulttargets屬性指定msbuild引擎從哪(幾)個target開始執行,也可以在調用msbuild.exe時使用t開關來手動指定將要運行的target,方法如下:



    msbuild /t:checkout



    這樣,只有checkout(以及它所依賴的target,在上文中沒有)會被執行。



    5. task元素。這可能是整個項目文件中最重要的,因為它才是真正可執行的部分(這也是為什么我在上面說target是虛擬的)。你可以在target下面放置多個task來順序地執行相應的任務,比如我在上面示例代碼中就在兩個不同的target中安排了makedir、csc和exec三個不同的task。這些task通過name屬性來相互區分,并各自擁有不同的其它屬性來完成不同的任務,比如csc有sources(源代碼文件)、targettype(目標類型)、outputassembly(生成程序集名稱)等屬性,而makedir則只需設置directories(需要創建的路徑名稱列表)即可。



    也許你會奇怪這些task的名稱和屬性從哪里來。好吧,請用文本編譯器打開%windir%/microsoft.net/framework/v1.2.30703/microsoft.buildtasks文件,看到了嗎?默認情況下里面應該是這樣的(不同的版本可能會有細微差別):



    <!-- this file lists all the tasks that ship by default with msbuild -->

    <defaulttasks>

    <usingtask taskname="microsoft.build.tasks.csc" assemblyname="msbuildtasks"/>

    <usingtask taskname="microsoft.build.tasks.msbuild" assemblyname="msbuildtasks"/>

    <usingtask taskname="microsoft.build.tasks.exec" assemblyname="msbuildtasks"/>

    <usingtask taskname="microsoft.build.tasks.vbc" assemblyname="msbuildtasks"/>

    <usingtask taskname="microsoft.build.tasks.makedir" assemblyname="msbuildtasks"/>

    <usingtask taskname="microsoft.build.tasks.resgen" assemblyname="msbuildtasks"/>

    <usingtask taskname="microsoft.build.tasks.copy" assemblyname="msbuildtasks"/>

    <usingtask taskname="microsoft.build.tasks.netassemblyresolver" assemblyname="msbuildtasks"/>

    <usingtask taskname="microsoft.build.tasks.transformpath" assemblyname="msbuildtasks"/>

    </defaulttasks>



    你會注意到,在defaulttasks元素下面排列的全是usingtask,其中指明每一個task的taskname(名稱)和assemblyname(程序集)。比如說第一個usingtask就對應著我們上面用過的csc任務,它的完整名稱(namespace+class)是microsoft.build.tasks.csc,位于msbuildtasks.dll程序集中(請在同一目錄下確認這一.dll文件的存在)。這樣,msbuild引擎在遇到對csc任務的調用時就會通過這里的注冊信息來確定csc所在的程序集,從而最終運行相應的托管代碼。這樣,如果你自己也寫了不同的task,請按同樣的方式對它進行注冊以便使用。如果你引用了一個還沒有注冊的target,那么msbuild引擎將無法找到它的存在而導致生成失敗。



    當然,msbuild task的注冊方式不止以上一種。以上注冊方法的影響范圍是全局,你可以在每一個project里應用上面注冊的那些task。但你也可以選擇在project范圍內注冊task,這將對應著另外一種略有不同的方法。我會在后面的一篇文章里給出具體介紹。在這里,你只需明白你所需要的task在哪里找到,而它們的具體用法可以通過參考msbuildtasks一文來獲得,在這里我就不細說了。



    ok,介紹了一長串,還是快點把我們的build.csproj運行起來吧。請在shell的同一目錄下輸入以下命令:



    msbuild



    或者:



    msbuild build.csproj



    運行結果如下:



    d:/dev/mymsbuilddemo>msbuild build.csproj

    msbuild build.csproj

    microsoft (r) .net build engine version 1.2.30703.4

    [microsoft .net framework, version 1.2.30703.4]

    copyright (c) microsoft corporation 2003. all rights reserved.



    target "build" in project "build.csproj"

    task "makedir"

    creating directory "bin".

    task "csc"

    csc.exe /out:"bin/hellomsbuild.exe" /target:exe "hellomsbuild.cs"



    target "run" in project "build.csproj"

    task "exec"

    hello msbuild!



    可見,在build.csproj指定的兩個target和三個task均按相應的順序依次運行,在csc執行時msbuild還顯示出了當前執行的具體命令,而在原來的visual studio .net年代,你是無法獲知當前正在執行的編譯命令是什么(據alex kipman稱,連visual studio .net自己也不知道正在執行的具體命令,因為那些命令已經被hard code進了“黑盒子”,根本無法提?。?br>


    好了,一個簡單的msbuild文件用法示例就到這兒了。如果你此前還沒接觸過msbuild或者nant,那么希望這篇文章能讓你對msbuild的用法有個初步的了解。還有很多的細節我在文中沒有涉及,如果你感興趣的話就請下載前面我提到的那些msbuild文檔來自己研究吧。我會在下一篇文章里介紹如何開發自己的msbuild task。


    發表評論 共有條評論
    用戶名: 密碼:
    驗證碼: 匿名發表
    主站蜘蛛池模板: 通渭县| 兴宁市| 射阳县| 囊谦县| 绵竹市| 沂源县| 临邑县| 汉寿县| 扎囊县| 双柏县| 那曲县| 黄龙县| 乌拉特后旗| 新邵县| 弥渡县| 革吉县| 泰宁县| 桑日县| 荃湾区| 卢氏县| 南汇区| 历史| 荥经县| 泾源县| 西丰县| 封开县| 张掖市| 基隆市| 沧源| 昌吉市| 潜江市| 宜昌市| 芦山县| 阜宁县| 许昌县| 台州市| 拉萨市| 钟山县| 松溪县| 明水县| 永仁县|