2016年12月7日 星期三

[iThome第8屆鐵人賽 06]開始建制一個Asp .Net Mvc專案

經過了幾天的理論介紹,我們開始要進入建制專案的部分。

我們會先拿一個Asp .net Mvc的網站作為第一個要建制的專案,所以我們會先建立出來,然後在使用MSBuild帶來的幫助,幫我們快速建立專案

這次的建制我們都是focus在.net Framework的部分,或許.net core會有所不同,但是概念是一樣。

(之後下面提到的code都可以從這邊看到內容:github repo,這篇會是tag sample/chapter6)

MSBuild和Psake的關係

在我們往下之前,有一個關係要在說明一下。我們使用psake並不是說要完全放棄MSBuild,反而是兩個結合在一起得到兩者的好處。

首先,我們知道VS其實有很多不同類型的專案,而這些不同類型的專案在建制過程呼叫方式都完全不太一樣。因此,微軟提供了很多不同project的msbuild target(同等於task的概念)來處理 怎麼建制這些專案和要copy那些檔案。

因此,我們不會重複造車輪,而是直接使用MSBuild所帶來的便利。

不過這個時候會好奇,那當初不就直接用MSBuild就好?

原因非常簡單,要擴充MSBuild非常麻煩。需要用C#才有辦法寫,然後又要處理一堆xml。

反過來看psake,非常簡單,只要定義一個powershell script就好。

所以,接下來我們會看到MSBuild被執行就沒什麼好奇怪。

準備程式用於做建制測試

我們需要先把環境準備好方便接下來的測試。

首先我們先建立一個Asp .net Mvc的專案,先看看有web專案情況會如何。

我們會建立一個asp .net mvc的專案,並且包含預設的Test專案

image
選擇asp .net web applicationimage

選擇Mvc,然後勾選unit test

開始建制我們的專案

基本上在建制專案的時候,有3個重要參數,說明一下:

  1. 建制模式 - 一般我們都會設定要用Debug還是Release(預設模式)
  2. 目標的platform - 一般有三個值,x64、x86和Any Cpu
  3. 建制結果的位置 - 要把建制結果放在那裡,以我們來說就是 .build\temp 裡面



1 和 2 其實 在VS裡面也可以設定,不過一般來說不怎麼調整就是 image
VS設定建制模式和目標platform的位置

有了這三個部分之後,我們就可以來調整我們Compile的Task

首先,剛剛提到的三個參數,第1和第2要增加,而第3我們已經有了。和其他參數一樣,我們會把這個加在properties裡面,這樣才有可能可以把值覆蓋。

Properties{
...
 $buildConfiguration = "Release"
 $buildTarget = "Any CPU"
}
   

再來的會就是我們實際的Compile task:

task Compile -depends Clean, Init -description "編譯程式碼" `
  -requiredVariables solutionFile, buildConfiguration, buildTarget, buildTempDirectory `
{ 
 Write-Host "開始建制檔案:$solutionFile"

 msbuild $solutionFile "/p:Configuration=$buildConfiguration;Platform=$buildTarget;OutDir=$buildTempDirectory"
}
   

這邊使用到了msbuild做實際的編譯,然後用到了requiredVariables去做參數的驗證。

這個時候我們就可以去執行build.ps1,會發現一切正常,但是有幾個小問題。

image
建制成功

修正Compile時候出現的幾個小問題

MSBuild使用的.Net版本錯了

首先從build的日誌裡面可以看到,我們使用的MSBuild版本是4.6,但是我們的.Net Framework卻是4.0,但是實際上我們的project是用4.5.2寫的。如果用到4.5.2才有的功能, 很可能導致編譯錯誤。

image
build到了4.0

這個很好解決,在Invoke-psake有個參數叫做framework,用這個可以設定build的target framework。

所以在build.ps1

Invoke-psake -buildFile .\default.ps1 -taskList Test `
    -framework "4.5.2" `
    -parameters @{
    "solutionFile" = (Get-ChildItem("..\*.sln")).FullName |
     Sort-Object $_ | select -Last 1
    }`
    -properties @{
    "testMsg"="測試訊息"
    }
   

Console看不出哪段是psake在執行

msbuild的內容比較多,造成看不太清楚那段屬於task記錄執行。不過psake有提供一個叫做FormatTaskName,能夠定義Task執行的時候顯示的內容。

default.ps1可以增加以下方法

FormatTaskName ("`r`n`r`n" + ("-"*25) + "[{0}]" + ("-"*25))
image
看起來區分比較明顯

結語

在這篇我們開始把psake和msbuild做了結合,並且把一個mvc網站建立了出來。

在下篇,我們會看看被compile出來的結果,和加入console和library專案,看看建制結果是否有不同。


4 則留言 :

  1. 請教您, 我照做這一系列的文章, 這篇新建MVC專案, 然後是要拷貝前面做的 build.ps1, defaut.ps1, 拷貝過來改是嗎?

    回覆刪除
  2. 作者已經移除這則留言。

    回覆刪除
  3. 我試出來了...
    是要一個方案裡面,包含
    1)Build(專案): 內含default.ps1, build.ps1, 並且安裝NuGet套件:psake
    2)MVC(專案)

    不過有新問題, compile還是有錯誤:
    -------------------------[Compile]-------------------------
    開始建制檔案:C:\_0AJ\0_work\zzMyGit\RDS2\1_work\WebRDS\WebRDS.sln
    Microsoft (R) Build Engine version 14.0.23107.0
    Copyright (C) Microsoft Corporation. 著作權所有,並保留一切權利。

    在這個方案中一次建置一個專案。若要啟用平行組建,請加入 "/m" 參數。
    已經開始建置於 2017/6/23 14:34:58。
    節點 1 (預設目標) 上的專案 "C:\_0AJ\0_work\zzMyGit\RDS2\1_work\WebRDS\WebRDS.sln"。
    ValidateSolutionConfiguration:
    建置方案組態 "Release|Any CPU"。
    專案 "C:\_0AJ\0_work\zzMyGit\RDS2\1_work\WebRDS\WebRDS.sln" (1) 正在節點 1 (預設目標) 上建置 "C:\_0AJ\0_work\zzMyGit\RDS2\1_work\WebRDS\WebRDS\WebRDS.csproj" (2)。
    C:\_0AJ\0_work\zzMyGit\RDS2\1_work\WebRDS\WebRDS\WebRDS.csproj(1,1): error MSB4041: 專案的預設 XML 命名空間必須是 MSBuild XML 命名空間。如果使用 MSBuild 2003 格式設計專案,請將 xmlns="http://schemas.m
    icrosoft.com/developer/msbuild/2003" 加入至 項目。如果是使用舊版的 1.0 或 1.2 格式設計專案,請將專案轉換為 MSBuild 2003 的格式。
    專案 "C:\_0AJ\0_work\zzMyGit\RDS2\1_work\WebRDS\WebRDS\WebRDS.csproj" (預設目標) 建置完成 -- 失敗。
    專案 "C:\_0AJ\0_work\zzMyGit\RDS2\1_work\WebRDS\WebRDS.sln" (1) 正在節點 1 (預設目標) 上建置 "C:\_0AJ\0_work\zzMyGit\RDS2\1_work\WebRDS\MyBuildProject\MyBuildProject.csproj" (3)。
    GenerateTargetFrameworkMonikerAttribute:
    將略過目標 "GenerateTargetFrameworkMonikerAttribute",因為所有輸出檔對於其輸入檔而言都已更新。
    CoreCompile:
    將略過目標 "CoreCompile",因為所有輸出檔對於其輸入檔而言都已更新。
    CopyFilesToOutputDirectory:
    正在將檔案從 "obj\Release\MyBuildProject.dll" 複製到 "C:\_0AJ\0_work\zzMyGit\RDS2\1_work\WebRDS\.build\temp\MyBuildProject.dll"。
    MyBuildProject -> C:\_0AJ\0_work\zzMyGit\RDS2\1_work\WebRDS\.build\temp\MyBuildProject.dll
    正在將檔案從 "obj\Release\MyBuildProject.pdb" 複製到 "C:\_0AJ\0_work\zzMyGit\RDS2\1_work\WebRDS\.build\temp\MyBuildProject.pdb"。
    專案 "C:\_0AJ\0_work\zzMyGit\RDS2\1_work\WebRDS\MyBuildProject\MyBuildProject.csproj" (預設目標) 建置完成。
    專案 "C:\_0AJ\0_work\zzMyGit\RDS2\1_work\WebRDS\WebRDS.sln" (預設目標) 建置完成 -- 失敗。

    建置失敗。

    "C:\_0AJ\0_work\zzMyGit\RDS2\1_work\WebRDS\WebRDS.sln" (預設目標) (1) ->
    "C:\_0AJ\0_work\zzMyGit\RDS2\1_work\WebRDS\WebRDS\WebRDS.csproj" (預設目標) (2) ->
    C:\_0AJ\0_work\zzMyGit\RDS2\1_work\WebRDS\WebRDS\WebRDS.csproj(1,1): error MSB4041: 專案的預設 XML 命名空間必須是 MSBuild XML 命名空間。如果使用 MSBuild 2003 格式設計專案,請將 xmlns="http://schemas
    .microsoft.com/developer/msbuild/2003" 加入至 項目。如果是使用舊版的 1.0 或 1.2 格式設計專案,請將專案轉換為 MSBuild 2003 的格式。

    0 個警告
    1 個錯誤

    經過時間 00:00:00.86
    完成 Compile !

    回覆刪除
    回覆
    1. 您的mvc是 asp .net core的嗎?您的錯誤訊息和這個有點類似 https://github.com/Microsoft/vsts-tasks/issues/3747
      如果是,因為目前我還沒在asp .net core上面build過,幫不了您。
      如果不是,你可以試試看從github下載我的範例嗎?https://github.com/alantsai-samples/devops-psake/releases/tag/sample%2Fchapter6
      您會需要用VS先把他打開,然後還原nuget package(script裡面忘記先restore,所以要手動做)
      然後用 powershell呼叫
      \src\BuildProject\build.ps1
      看看有沒有成功。
      如果有成功(表示script沒有問題,可能是建立出來的專案問題),看是否能夠提供您不能成功的範例程式給我,和您目前使用的VS版本,我幫您試試看

      刪除