<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      MSBuild簡單介紹

      背景


      托博客園的福,上周六,有家開發(fā)醫(yī)療行業(yè)系統(tǒng)的初創(chuàng)公司聯(lián)系我,說在博客園上看到我關于WPF的幾篇文章,邀請我去他們那里交流WPF相關的技術知識和心得體會。作為非大拿的我自然是受寵若驚,但對方好意相約,我便欣然前往。

      諸事按過不表,在交流過程中,談到了單獨一個產(chǎn)品的版本控制的問題。

      (以下該公司人員簡稱為對方)

      對方:“我們用SVN,還不錯。只是現(xiàn)在產(chǎn)品的版本越來越多。”

      我:“怎么說?”

      對方:“我們開發(fā)平臺有2.0、4.0,目前正在嘗試4.5,特性和語法還是有些許不一樣的。但是我們不可能為每個.net framework單獨維護一個解決方案。少數(shù)不同的地方,我們采用SVN分支的方式進行。”

      我:“你們產(chǎn)品的市場版本應該也有若干個吧……”

      對方:“唔,客戶的需求大同小異,所以我們的版本是按模塊和功能的不同而區(qū)分的,比如標準版、決策分析版、旗艦版等等,但每個版本具體到某個模塊,基本上保持一致,偶爾需要微調下。”

      我:“微調也是通過SVN來管理?”

      對方:“是的,所以現(xiàn)在分支越來越多,其實代碼都大同小異。”

      我:“哦,我沒理解錯的話,很多情況下,當主干代碼修改了,那所有的這些分支都需要進行相應的合并?”

      對方:“是這樣沒錯,有時候想想,如果主干修改的內容能自動無錯地合并到分支就好了。”

      我:“SVN我只會簡單使用,不過我認為你們的這種情況,可以使用另一種方式——vs原本就支持的……”

      說到這里,對方的眼睛突然亮了,我和他相視一笑,我知道他也想到了。這也暗合了我自己總結的一套哲理中的其中一條:汝握秘之鑰,just forget it。而這么顯而易見的處理方法被整個開發(fā)團隊忽略,這是一個典型的“群體性失明”案例。

      “MD,早該想到,條件編譯符號!”

      沒錯,條件編譯符號結合#if、#else、#endif之類,恰當?shù)厥褂盟鼈儯梢詫VN的各個分支重新整合在一起(當然并行開發(fā)過程仍然需要SVN進行管控)。前提是各分支不要有太大差異,有些分支項目結構都變了,那更沒必要整在一起了。

      各位看官,是不是有點疑惑——不是說MSBuild嗎,怎么扯到條件編譯符號上去了?

      隔天晚上,我正在安裝前幾天卸載掉的快播軟件,準備用來觀看這兩天落下的新聞聯(lián)播時,手機響了,是上面那家公司的技術主管(以下仍稱對方)。在這個關鍵時刻打我電話,肯定是發(fā)生了緊急的事情,于是我淡定地按了接聽鍵。

      對方:“XX,我們用WPF版本的項目做整合,發(fā)現(xiàn)有個問題。”

      我:“不會吧,什么問題?”

      對方:“代碼文件沒問題,通過條件編譯符號能生成特定版本的程序集,但是xaml文件似乎并不支持#if、#elif這些指令。”

      我一驚:“what?!”

      對方:“某些情況,我們通過binding方式,就是說,在代碼文件中根據(jù)編譯符號設置某一屬性的值,然后前臺根據(jù)這個值來顯示特定版本的內容。但是另外有些情況不曉得怎么處理。電話說不清楚,我發(fā)你QQ。”

      掛了電話,我不情愿地中止了快播安裝進程,打開QQ,一段代碼跳了出來。

       1 <!--SmartGridView.Title綁定至后臺代碼,可以在后臺通過條件編譯符號設置合適的值-->
       2 <his:SmartGridView AutoGenerateColumns="True"                   
       3                    Title="{Binding Title}"
       4                    ItemsSource="{Binding GridDataItems}">
       5     <!--當為版本A時,需要下面這段代碼,其余版本不需要-->
       6     <his:SmartGridView.RowDetailsTemplate>
       7         <DataTemplate>
       8             <his:MedicineStockDetailsTemplate />
       9         </DataTemplate>
      10     </his:SmartGridView.RowDetailsTemplate>
      11     <!--當為版本A時,需要上面這段代碼,其余版本不需要-->
      12 </his:SmartGridView>

      對方表示第6行到第10行是目前難點所在。我半晌之后回過神,確實,編譯指令+條件編譯符號對cs文件有用,在xaml中能結合binding達到一部分效果,當遇到一段xaml要么存在,要么不存在的情況,這三者就無能為力了。怎么辦?

      我查閱頭腦中的知識庫,無果,上網(wǎng)搜索也沒搜出個所以然來,難道又要怪微軟這個坑爹貨,不在xaml中加入預編譯指令這么拉轟的功能?正當拙計之時,猛然發(fā)現(xiàn)有個單詞在谷歌的懷抱中向我拋著媚眼,定睛一看——“MSBuild”!

       基本概念


      MSBuild基于項目文件發(fā)揮作用。我們以Visual C# 項目文件為例。當在Visual Studio中新建一個項目,VS自動給我們生成了一個.csproj項目文件。一個典型的項目文件格式如下:

       1 <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
       2   <PropertyGroup>
       3     <AssemblyName>MSBuildSample</AssemblyName>
       4     <OutputPath>Bin\</OutputPath>
       5   </PropertyGroup>
       6   <ItemGroup>
       7     <Compile Include="helloworld.cs" />
       8   </ItemGroup>
       9   <Target Name="Build" Inputs="@(Compile)" Outputs="$(OutputPath)$(AssemblyName).exe">
      10     <MakeDir Directories="$(OutputPath)" Condition="!Exists('$(OutputPath)')" />
      11     <Csc Sources="@(Compile)" OutputAssembly="$(OutputPath)$(AssemblyName).exe" />
      12   </Target>
      13   <Target Name="Clean" >
      14     <Delete Files="$(OutputPath)$(AssemblyName).exe" />
      15   </Target>
      16   <Target Name="Rebuild" DependsOnTargets="Clean;Build" />
      17 </Project>
      • 其中PropertyGroup定義各種屬性鍵值對,類似于字符串變量;
      • ItemGroup定義各種項,項可以有元數(shù)據(jù)(MetaData),我們可以將之看作對象(class),一般用于定義文件/文件夾;
      • Target,目標,其中一般包含若干Task,針對生成程序集這個過程來講,Target即為執(zhí)行一系列任務完成的一個生成步驟,當預定的所有生成步驟都完成之后,程序集也就生成成功了。
      • 以$(PropertyName)方式獲取屬性值;
      • @(ItemType)語法引用項,直接打印為Include指定的字符串,要獲取項的元數(shù)據(jù),使用%(ItemType.MetaDataName);
      • 可以將項列表轉換為新的項列表。語法:@(ItemType -> '%(MetadataName)')。當然右邊可以是任意你想要的格式,可以使用屬性、函數(shù)或自定義字符串等等;
      • Target中設置Inputs和Outputs屬性將改變該步驟為增量模式,即MSBuild會比對這兩者之間最晚的文件修改時間以決定是否執(zhí)行該步驟;
      • Target中的DependsOnTargets表示該Target依賴于其它Target,其它Target執(zhí)行完畢之后該Target才能執(zhí)行,且其它Target的執(zhí)行順序為DependsOnTargets中定義的順序。
      • 另外,幾乎所有MSBuild元素都可以有Condition特性,只有當Condition的計算結果為“true”時,才會定義或重新定義相關元素。

      假設上述文件保存為Test.csproj,我們可以在Visual Studio 命令提示鍵入

      msbuild Test.csproj /t:Rebuild

      /t表示要執(zhí)行的Target,若去除/t:Rebuild,則會執(zhí)行Build Target,因為Project節(jié)點有個DefaultTargets,指定了默認的Target。

      以上為基本概念,詳情請參看:演練:使用 MSBuild

      進階


      1. 有些系統(tǒng)預定義的Target.前邊說道vs會幫我們自動生成一個項目文件,用記事本打開看,會發(fā)現(xiàn)Project的DefaultTargets="Build",但是文件中并未定義名稱為"Build"的Target,這就是系統(tǒng)預定義的。另外末尾有兩個被注釋掉的Target,在Build Target執(zhí)行前后要做些額外事情,我們就可以使用它們.
      2. 項(Item)也有很多預定義的元數(shù)據(jù),比如Filename、Extension、FullPath,從字面就能理解它們的意思,具體請看MSBuild: By Example—Introducing Well-Known Metadata;
      3. 也有若干保留屬性,參考MSBuild 保留屬性
      4. 在 .NET Framework 4 版和 4.5 版中,可以使用屬性函數(shù)來計算 MSBuild 腳本。參考屬性函數(shù)
      5. 動態(tài)創(chuàng)建項.有時候需要根據(jù)已有條件創(chuàng)建新項,比如在磁盤中動態(tài)生成了一些文件,我們就可以為這些文件創(chuàng)建對應的項,以便使之有機會參與Build的過程.注意項Include特性指向的文件如果不存在,在生成過程中可能會拋出error導致生成中止.3.5之前,可以使用CreateItem;3.5及以后版本對這方面做了改進,可以直接在Target中嵌入ItemGroup,不但能創(chuàng)建新Item,還能Remove或者Modify原有的Item.參考CreateItem vs ItemGroup;
      6. 前邊說過Target里包含若干Task,表示按順序執(zhí)行的步驟,咱們也可以自定義Task.比如自定義了一個Task名稱為PreprocessXaml,它包含在BuildTasks.dll的程序集中,可以使用以下方式獲得該Task的引用.
        1 <PropertyGroup>
        2   <BuildTasksPath Condition="'$(BuildTasksPath)' == ''">..\BuildTasks\</BuildTasksPath>
        3   <BuildTasksLib>$(BuildTasksPath)BuildTasks.dll</BuildTasksLib>
        4 </PropertyGroup>
        5 
        6 <UsingTask AssemblyFile="$(BuildTasksLib)" TaskName="PreprocessXaml" />

        然后可以這么使用之.

        <Target Name="MyTarget">
          <PreprocessXaml SourceFile="%(PreprocessedXaml.FullPath)"
                                        DestinationFile="$(ProjectDir)%(PreprocessedXaml.OutputFile)">
          </PreprocessXaml>
        </Target>

        更多參考Best Practices For Creating Reliable Builds, Part 2;

      7. 第1條說道我們可以在項目文件末尾取消默認注釋掉的兩個Target,在其中插入我們想要在Build之前之后執(zhí)行的邏輯.當然還有另一種方法,覆蓋預定義的BuildDependsOn屬性.
        <PropertyGroup>
          <BuildDependsOn>
            MyBeforeTarget;
            $(BuildDependsOn);
            MyAfterTarget;
          </BuildDependsOn>
        </PropertyGroup>

        還有其它預定義東東可以覆蓋,更多詳情:如何:擴展 Visual Studio 生成過程;

      8. 除了在項目文件中寫一份完整的MSBuild文檔,還可以將之分離成多個.targets格式文件,targets文檔格式同.csproj/.vbproj文件.then我們可以在項目文件中使用<Import Project=".XXX.targets" />引入,targets文件也能引入其它targets,MSBuild根據(jù)引入順序執(zhí)行生成過程;
      9. 生成過程如果出錯,就會終止,而使用vs不能像普通項目一樣進行運行時調試.往往出錯都是出自自定義Task,Task有個Log對象,我們可以使用它在vs底部的錯誤列表中輸出錯誤\警告\普通消息.如base.Log.LogErrorFromException(exception);  

      使用MSBuild給XAML增加條件編譯符號的支持


      概念方面,算是基本把該寫到的點都寫到,哎,累了,特別是這種相對枯燥的概念學習、解釋、搬運,剛開始根本無從下手,各種繁雜困惑。接下去就是完成咱們最初的目的。大家先自己思考下怎么個方案可行。這下篇再寫吧。剛說了,哥累了。

       

      轉載請注明本文出處:http://www.rzrgm.cn/newton/p/3156873.html 

      posted @ 2013-07-01 10:19  萊布尼茨  閱讀(6810)  評論(7)    收藏  舉報
      主站蜘蛛池模板: 猫咪www免费人成网站| 资源在线观看视频一区二区| 亚洲男人第一无码av网| 高中女无套中出17p| 人人澡超碰碰97碰碰碰| 国产精品中文一区二区| 性xxxx视频播放免费| 国产日韩入口一区二区| 无码人妻aⅴ一区二区三区蜜桃| 成人3D动漫一区二区三区| 日韩国产中文字幕精品| 国产WW久久久久久久久久| 国产一区日韩二区欧美三区| 亚洲国产大胸一区二区三区| 鄂尔多斯市| 人妻丰满熟妇av无码区| 亚洲综合无码一区二区| 久久人妻无码一区二区三区av| 国产精品尤物午夜福利| 国产精品免费无遮挡无码永久视频 | 少妇扒开双腿自慰出白浆 | 国产网友愉拍精品视频手机| 国产成人精品1024免费下载| 国产成人精品一区二区| 亚洲精品一区二区制服| 日韩精品一区二区三区激情| 国产aⅴ夜夜欢一区二区三区| 在线观看美女网站大全免费| 四虎永久精品免费视频| japanese边做边乳喷| 国产999久久高清免费观看| 免费AV片在线观看网址| 麻豆麻豆麻豆麻豆麻豆麻豆| 亚洲欭美日韩颜射在线二| 国产精品老熟女露脸视频| 欧美成年性h版影视中文字幕| 韩国精品一区二区三区在线观看| 国产福利酱国产一区二区| 啦啦啦高清在线观看视频www| 粉嫩小泬无遮挡久久久久久| 国产精品剧情亚洲二区|