# C# Solution Build via MSBuild
## 安裝各版本MSBuild
- MsBuild v14
1. 下載安裝檔並安裝即可,安裝檔位置可參考[**相關資源章節**](#相關資源)。
- MsBuild v15以上(v15、v16...)
1. 僅支援 Windows8.1(Windows Server 2012 R2)以上作業系統。
2. 由 Visual Studio Subscriptions 下載並安裝(公司有買)。

- 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 目錄下所有的憑證(右鍵=>安裝憑證)。


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=\"Web\" /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=)