---
# System prepended metadata

title: C# Solution Build via MSBuild
tags: [ITSOWER]

---

# C# Solution Build via MSBuild

## 安裝各版本MSBuild
- MsBuild v14
    1. 下載安裝檔並安裝即可，安裝檔位置可參考[**相關資源章節**](#相關資源)。
- MsBuild v15以上（v15、v16...）
    1. 僅支援 Windows8.1(Windows Server 2012 R2)以上作業系統。
    2. 由 Visual Studio Subscriptions 下載並安裝(公司有買)。
    ![](https://i.imgur.com/x48Rltb.jpg)
- MsBuild v15 以上產生離線安裝包
Visual Studio Subscriptions 下載的安裝檔，安裝時還需要連線，如果建置環境無法對外連線時，需先自行產生離線安裝包。
1. 使用命令提示字元執行指令產生Msbuild離線安裝檔，可用於建置 .Net Framework 和 .Net Core，`D:\Temp` 自行改自己的輸出目錄：
※以上圖的Build Tools for Visual Studio 2019 (version 16.5)為例
```
vs_buildtools__616596134.1504453580.exe --layout D:\Temp --add Microsoft.VisualStudio.Workload.MSBuildTools --add Microsoft.VisualStudio.Workload.WebBuildTools --add Microsoft.VisualStudio.Workload.NetCoreBuildTools --includeRecommended --includeOptional --lang zh-TW
```
- MsBuild v16.5 離線安裝包
1. 將離線安裝包的資料夾，複製到目標建置用主機。
2. 安裝資料夾中 certificates 目錄下所有的憑證（右鍵=>安裝憑證）。
![](https://i.imgur.com/5epMNIN.png)
![](https://i.imgur.com/cSz90Lx.png)
3. 使用命令提示字元執行指令安裝
```
vs\_buildtools\_*.exe --noweb
```

## MsBuild版本的選擇
- 建議選用較新的版本，除非建置環境（不是開發環境跟生產環境）作業系統無法安裝新版本，再選用v14。

## MsBuild位置（僅供參考，實際情況可能有差異）
- MsBuild v14
`C:\Program Files (x86)\MSBuild\14.0\Bin＼Msbuild.exe`
- MsBuild v15 以上
`C:\Program Files (x86)\Microsoft Visual Studio\[Visual Studio版號]\BuildTools\MSBuild\Current\Bin＼Msbuild.exe`

## 建置指令（基本指令，請自行依需求調整）
```
MsBuild.exe [Sln位置] /p:Configuration=Release
```

## Microsoft.Net.Compilers
新版的C#採用 Roslyn 編譯平台，其中有一個功能是讓 .NET Compiler 變成可攜的，並內建於專案內。因此我們專案會用Nuget載一個C#版本 Microsoft.Net.Compilers 與 的套件。

- 目前模板專案使用 Microsoft.Net.Compilers 2.9的版本，因此如果沒有特別再更新，則開發時C#語法只能使用到C# 7.3，使用的MsBuild則需要為Visual Studio 2017 version 15.7版本(詳請參照下面版本對照列表)。

- 若建置環境只能安裝到 MsBuild v14 的版本，則 Microsoft.Net.Compilers 應降板至1.x，程式內語法最多只能使用到 C#6.0 的語法。

### Microsoft.Net.Compilers 與 C#版本及 MsBuild版本對照[[Click me]](https://github.com/dotnet/roslyn/wiki/NuGet-packages)：
> * Versions 1.x mean C# 6.0 and VB 14 (Visual Studio 2015 and updates). For instance, 1.3.2 corresponds to the most recent update (update 3) of Visual Studio 2015.
> * Version 2.0 means C# 7.0 and VB 15 (Visual Studio 2017 version 15.0).
> * Version 2.1 is still C# 7.0, but with a couple fixes (Visual Studio 2017 version 15.1).
> * Version 2.2 is still C# 7.0, but with a couple more fixes (Visual Studio 2017 version 15.2). Language version "default" was updated to mean "7.0".
> * Version 2.3 means C# 7.1 and VB 15.3 (Visual Studio 2017 version 15.3). For instance, 2.3.0-beta1 corresponds to Visual Studio 2017 version 15.3 (Preview 1).
> * Version 2.4 is still C# 7.1 and VB 15.3, but with a couple fixes (Visual Studio 2017 version 15.4).
> * Version 2.6 means C# 7.2 and VB 15.5 (Visual Studio 2017 version 15.5).
> * Version 2.7 means C# 7.2 and VB 15.5, but with a number of fixes (Visual Studio 2017 version 15.6).
> * Version 2.8 means C# 7.3 (Visual Studio 2017 version 15.7)
> * Version 2.9 is still C# 7.3 and VB 15.5, but with more fixes (Visual Studio 2017 version 15.8)
> * Version 2.10 is still C# 7.3 and VB 15.5, but a couple more fixes (Visual Studio 2017 version 15.9)
> * Version 3.0 includes a preview of C# 8.0 (Visual Studio 2019 version 16.0), but 2.11 was used for preview1.
> * Version 3.1 includes a preview of C# 8.0 (Visual Studio 2019 version 16.1)
> * Version 3.2 includes a preview of C# 8.0 (Visual Studio 2019 version 16.2)
> * Version 3.3 includes C# 8.0 (Visual Studio 2019 version 16.3, .NET Core 3.0)
> * Version 3.4 includes C# 8.0 (Visual Studio 2019 version 16.4, .NET Core 3.1)
> * See the history of C# language features for more details.

## 其他常見問題
### bin 目錄下的 roslyn 資料夾在建置後未生成
像是 ASP.Net Mvc 因為 View 需要動態編譯，所以除了Microsoft.Net.Compilers外，還會引用Microsoft.CodeDom.Providers.DotNetCompilerPlatform 套件，建置時會在 bin 目錄產生 roslyn 資料夾，放置編譯需要的編譯器等。
但由 Visual Studio 2015 或更低版本建立的專案升級為 Visual Studio 2019 專案後，因升級後csproj檔通常會未針對此調整，所以不會自動在 bin 目錄下生成 roslyn 資料夾，因此導致執行階段在編譯如 View 的程式碼時因找不到 csc.exe 出錯。
1. 解決方法1（不建議）：
手動從自己開發環境的專案上，複製 bin 目錄的 roslyn 資料夾到生產環境。
3. 解決方法2：
修改專案檔(.csproj)，設定 AfterBuild 事件將 csc.exe 複製至正確位置。
```xml
<Target Name="CopyRoslynFiles" AfterTargets="AfterBuild" Condition="!$(Disable_CopyWebApplication) And '$(OutDir)' != '$(OutputPath)'">
    <ItemGroup>
    <RoslynFiles Include="$(CscToolPath)\*" />
    </ItemGroup>
    <MakeDir Directories="$(WebProjectOutputDir)\bin\roslyn" />
    <Copy SourceFiles="@(RoslynFiles)" DestinationFolder="$(WebProjectOutputDir)\bin\roslyn" SkipUnchangedFiles="true" Retries="$(CopyRetryCount)" RetryDelayMilliseconds="$(CopyRetryDelayMilliseconds)" />
</Target>
```
### Microsoft.Net.Compilers 降版後發生錯誤無法建置
> **錯誤訊息**
> CSC : error CS1617: Invalid option 'latest' for /langversion; must be ISO-1, ISO-2, Default or an integer in range 1 to 6.

此錯誤是在有安裝 Microsoft.CodeDom.Providers.DotNetCompilerPlatform 時，切換.Net Framework版本或更新 Microsoft.Net.Compilers 版本時，系統未自動調整config檔或csporj檔所致。

- 調整 app.config 或 web.config：
將`compilerOptions="/langversion:**default**` 的 langversion 改為錯誤訊息要求的  ISO-1, ISO-2, Default or an integer in range 1 to 6，這邊xml的defalut已經符合要求選項中的Default值了，如果還是不過的話，就調整.csproj檔。

```xml
    <system.codedom>
        <compilers>
            <compiler language="c#;cs;csharp" extension=".cs"
                type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                warningLevel="4" compilerOptions="/langversion:default /nowarn:1659;1699;1701"/>
            <compiler language="vb;vbs;visualbasic;vbscript" extension=".vb"
                type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                warningLevel="4" compilerOptions="/langversion:default /nowarn:41008 /define:_MYTYPE=\&quot;Web\&quot; /optionInfer+"/>
        </compilers>
    </system.codedom>
```

- 調整 csproj 檔：
將 LangVersion 值由原本的值[latest]改為要求的[Defalut]。

```xml
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <PlatformTarget>AnyCPU</PlatformTarget>
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>bin\Debug\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
    <LangVersion>Default</LangVersion>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <PlatformTarget>AnyCPU</PlatformTarget>
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>bin\Release\</OutputPath>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
    <LangVersion>Default</LangVersion>
  </PropertyGroup>
```

## 相關資源
### MSBuild 測試環境
公司192.168.100.82上有安裝MsBuild的Version 14和Version 16.5兩個版本。
### MSBuild 離線安裝包
放置於 `\\40.83.98.71\Software\程式開發\MsBuildTools`，目前有v14和v16.5兩個版本。
### MSBuild 下載位置
Visual Studio Subscriptions：[https://my.visualstudio.com/Downloads?q=Build%20Tools&pgroup=](https://my.visualstudio.com/Downloads?q=Build%20Tools&pgroup=)