VS Code リモート開発で .NET Framework の .exe をビルドしてみた
Tags: dotnet, dotnetcore, vscode, docker
Published: 2019-09-20 14:03:27

---
title: VS Code リモート開発で .NET Framework の .exe をビルドしてみた
published: true
tags: dotnet,dotnetcore,vscode,docker
canonical_url: https://medium.com/@joni2nja/vs-code-remote-development-build-net-framework-89eaa99d96d1
---
This post originally appeared on [Medium](https://medium.com/@joni2nja/vs-code-remote-development-build-net-framework-89eaa99d96d1)

___

### VS Code リモート開発で .NET Framework の .exe をビルドしてみた

#### Linux/Mac環境で .NET Framework プロジェクトをビルド可能に～

![](https://cdn-images-1.medium.com/max/960/1*s5i5PA6XT8TCN593JOy5AQ.png)<figcaption>Visual Studio Code</figcaption>

以前 Twitter で見たのですが、Linux/Mac 環境でフル .NET Framework をターゲットし、ビルドができるらしい。

{% tweet 1135172099499331584 %}

[.NET Framework Targeting Pack Nuget Packages (Preview)](https://github.com/Microsoft/dotnet/tree/master/releases/reference-assemblies)

できるとのことなので、Linux マシンで普通にビルドしても面白くないので、今回は [Visual Studio Code Remote Development（リモート開発）](https://code.visualstudio.com/docs/remote/remote-overview)を使って、ビルドして検証してみたいと思います。

まずは VS Code を起動し、 `F1` 押下、コマンドを打ちます。 `rem ad` という風に必要最低限の文字列を打つだけで検索結果がヒットしますので、凄く便利です。

![](https://cdn-images-1.medium.com/max/666/1*lBGmKFSgzCachLMogfDfAg.png)<figcaption>必要最低限の文字列を打つことで検索</figcaption>

`C# (.NET Core Latest)` を選択します。

![](https://cdn-images-1.medium.com/max/624/1*EWbxnWoo_IQbu7So5i7b6Q.png)<figcaption>C# (.NET Core Latest) を選択</figcaption>

`Reopen in Container` を選択します。

![](https://cdn-images-1.medium.com/max/470/1*JCi4NBxgO4B3h-6hesbPhg.png)<figcaption>Reopen in Container を選択</figcaption>

そして、開きました。

![](https://miro.medium.com/max/3096/1*T0wV1BrjBg4OiG16_-6EQw.png)
[(高解像度画像を表示)](https://miro.medium.com/max/3096/1*T0wV1BrjBg4OiG16_-6EQw.png)

左側は [Windows Terminal](https://devblogs.microsoft.com/commandline/introducing-windows-terminal/) で `docker events` コマンドの結果をリアルタイムで表示しています。右側は VS Code リモート開発の準備ができた画面です。

VS Code の Terminal で `dotnet new console` を打って新規コンソールアプリケーションを作成します。

![](https://cdn-images-1.medium.com/max/1024/1*Ez-jEUAp5G0kx0Ms94i2FQ.png)<figcaption>dotnet new console</figcaption>
[(高解像度画像を表示)](https://miro.medium.com/max/1263/1*Ez-jEUAp5G0kx0Ms94i2FQ.png)

プロジェクトファイルを生成され、デフォルトで .csproj ファイルはこんな感じで作られます。

![](https://cdn-images-1.medium.com/max/545/1*D1-QC-box0tbK5HH9kF3vw.png)<figcaption>作成された .csproj ファイル</figcaption>

`netcoreapp2.2` を削除して、 `net48` に変更します。 `net48` は [.NET Framework 4.8 の TFM (Target Framework Monikers)](https://docs.microsoft.com/en-us/dotnet/standard/frameworks#supported-target-framework-versions) です。

`dotnet build` コマンドでビルドをしてみると、エラーです。

![](https://cdn-images-1.medium.com/max/1000/1*EE26QU-2KG-_dh8HjPdlDw.png)<figcaption>dotnet build でビルド</figcaption>
[(高解像度画像を表示)](https://miro.medium.com/max/1215/1*EE26QU-2KG-_dh8HjPdlDw.png)

まあ、エラーは当たり前ですね。Linux 環境で普通に .NET Framework プロジェクトをビルドできない訳ですから。ビルドできるようにするには **Microsoft .NET Framework Reference Assemblies** が必要です。`PackageReference` で定義し、再度ビルドしてみます。

![](https://cdn-images-1.medium.com/max/1024/1*ysVshjgnJodoh87esvK_6w.png)<figcaption>PackageReference 追加</figcaption>
[(高解像度画像を表示)](https://miro.medium.com/max/1960/1*ysVshjgnJodoh87esvK_6w.png)

お～！(≧▽≦)

宣伝通り、ビルドできましたね！  
.exe ファイルちゃんと生成されています！

[NuGet](https://www.nuget.org/packages/Microsoft.NETFramework.ReferenceAssemblies/1.0.0-preview.2) サイトで `Microsoft.NETFramework.ReferenceAssemblies` を覗いてみましょう。

![](https://cdn-images-1.medium.com/max/956/1*YZaGST72XhQHz3xRtxEm8Q.png)<figcaption>NuGet: Microsoft.NETFramework.ReferenceAssemblies</figcaption>

.NET Framework 4.8 はもちろんのこと、さかのぼって古い .NET Framework 2.0 も対応？！ これは凄くないですか！レガシーシステム向けでちゃんと Microsoft がサポートしているということですね。

はい、次！試しに、 `dotnet run` を実行してみます。

![](https://cdn-images-1.medium.com/max/1024/1*FGUmtDEnsnAD3QFnUYQiRQ.png)<figcaption>dotnet run エラー</figcaption>
[(高解像度画像を表示)](https://miro.medium.com/max/1960/1*FGUmtDEnsnAD3QFnUYQiRQ.png)

エラーです。これも当然のことですね。

```
System.ComponentModel.Win32Exception (8): Exec format error
   at Interop.Sys.ForkAndExecProcess(String filename, String[] argv, String[] envp, String cwd, Boolean redirectStdin, Boolean redirectStdout, Boolean redirectStderr, Boolean setUser, UInt32 userId, UInt32 groupId, Int32& lpChildPid, Int32& stdinFd, Int32& stdoutFd, Int32& stderrFd, Boolean shouldThrow)
   at System.Diagnostics.Process.StartCore(ProcessStartInfo startInfo)
   at System.Diagnostics.Process.Start()
   at Microsoft.DotNet.Cli.Utils.Command.Execute()
   at Microsoft.DotNet.Tools.Run.RunCommand.Start()
   at Microsoft.DotNet.Tools.Run.RunCommand.Run(String[] args)
   at Microsoft.DotNet.Cli.Program.ProcessArgs(String[] args, ITelemetry telemetryClient)
   at Microsoft.DotNet.Cli.Program.Main(String[] args)
```

`Win32Exception` 例外発生しましたね。

`dotnet run` は .NET Core アプリを実行するコマンドですが、生成された .exe ファイルを bash で直接実行したらどうなるでしょう？

![](https://cdn-images-1.medium.com/max/1024/1*gphtjbIHgMQOVakYmMBH7g.png)<figcaption>bash でバイナリを実行する</figcaption>
[(高解像度画像を表示)](https://miro.medium.com/max/1960/1*gphtjbIHgMQOVakYmMBH7g.png)

当然ながら、 .exe ファイルを Linux 上で直接実行できないよ～！

では、 Windows Explorer を開きます。

![](https://cdn-images-1.medium.com/max/976/1*fa32DsSmOcqTRojN2u3SxQ.png)<figcaption>Windows Explorer を開く</figcaption>

そこからダブルクリックし、実行します！

![](https://miro.medium.com/max/1954/1*KWFhlFZgE5vEQa3tYxzG1g.png)
[(高解像度画像を表示)](https://miro.medium.com/max/1954/1*KWFhlFZgE5vEQa3tYxzG1g.png)

おぉ～～！

非常にシンプルなコンソールアプリの検証になりますが、 Linux 環境でビルドした .NET Framework .exe ファイルはちゃんと Windows で実行できたことをこれで証明されましたね！🎉🎉🎉

ここまでは一応検証目標を達成しましたが、今度はマルチターゲットを検証してみたいと思います。

`TargetFramework` を修正し、複数の .NET Framework を対象にしてビルドしたいと思います。下記のように修正してビルドします。

```
<TargetFrameworks>net48;netcoreapp2.2</TargetFrameworks>
```

⚠注：TargetFramework ではなく 複数形 TargetFramework **s** （語尾に「s」）

![](https://cdn-images-1.medium.com/max/1024/1*PD_DGG9iFHqQgIQJw7v1HQ.png)<figcaption>マルチターゲット</figcaption>
[(高解像度画像を表示)](https://miro.medium.com/max/1960/1*PD_DGG9iFHqQgIQJw7v1HQ.png)

これで .NET Framework 4.8 と .NET Core 2.2 それぞれのバイナリが出来上がりました！👏👏👏

[dnSpy](https://github.com/0xd4d/dnSpy) で覗いてみましょう。

![](https://cdn-images-1.medium.com/max/1024/1*YOzayLn4JPA1TZTekueqUg.png)<figcaption>dnSpy で確認</figcaption>
[(高解像度画像を表示)](https://miro.medium.com/max/1636/1*YOzayLn4JPA1TZTekueqUg.png)

Linux 環境で .NET Core 2.2 の .dll を実行してみましょう！

![](https://cdn-images-1.medium.com/max/1024/1*arTM_Ist5Af9SLgSjMNl2g.png)<figcaption>bash で実行</figcaption>
[(高解像度画像を表示)](https://miro.medium.com/max/1960/1*arTM_Ist5Af9SLgSjMNl2g.png)

```
Hello World!
```

実行できましたね。

Windows Explorer を起動します。

![](https://cdn-images-1.medium.com/max/976/1*ph6McURoiKTwfDmmMyJi-Q.png)<figcaption>Windows Explorer</figcaption>

そこから、アドレスバーで `cmd` を打って、

![](https://cdn-images-1.medium.com/max/976/1*SM9L1_668T6jFW3GdW63wQ.png)<figcaption>cmd</figcaption>

ENTERキー押下！これで Explorer で開いているディレクトリがカレントディレクトリとして設定され cmd を起動されます。

先ほどと同じコマンド `dotnet RefAsm.dll` を実行します。

![](https://cdn-images-1.medium.com/max/1024/1*oyERn0sZybZOPVXNmAQEIg.png)<figcaption>Hello World!</figcaption>
[(高解像度画像を表示)](https://miro.medium.com/max/1953/1*oyERn0sZybZOPVXNmAQEIg.png)

Windows でも実行できてますね！

そう、 .NET Core は[クロスプラットフォーム](https://docs.microsoft.com/ja-jp/dotnet/core/)なのです ✨✨✨