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

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

Joni 【ジョニー】
9 min readSep 19, 2019
Visual Studio Code

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

https://twitter.com/RehanSaeedUK/status/1135172099499331584?s=20

.NET Framework Targeting Pack Nuget Packages (Preview):

できるとのことなので、Linux マシンで普通にビルドしても面白くないので、今回は Visual Studio Code Remote Development(リモート開発)を使って、ビルドして検証してみたいと思います。

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

必要最低限の文字列を打つことで検索

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

C# (.NET Core Latest) を選択

Reopen in Container を選択します。

Reopen in Container を選択

そして、開きました。

左側は Windows Terminaldocker events コマンドの結果をリアルタイムで表示しています。右側は VS Code リモート開発の準備ができた画面です。

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

dotnet new console

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

作成された .csproj ファイル

netcoreapp2.2 を削除して、 net48 に変更します。 net48.NET Framework 4.8 の TFM (Target Framework Monikers) です。

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

dotnet build でビルド

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

PackageReference 追加

お~!(≧▽≦)

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

NuGet サイトで Microsoft.NETFramework.ReferenceAssemblies を覗いてみましょう。

NuGet: Microsoft.NETFramework.ReferenceAssemblies

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

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

dotnet run エラー

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

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 で直接実行したらどうなるでしょう?

bash でバイナリを実行する

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

では、 Windows Explorer を開きます。

Windows Explorer を開く

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

おぉ~~!

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

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

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

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

⚠注:TargetFramework ではなく 複数形 TargetFrameworks (語尾に「s」)

マルチターゲット

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

dnSpy で覗いてみましょう。

dnSpy で確認

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

bash で実行
Hello World!

実行できましたね。

Windows Explorer を起動します。

Windows Explorer

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

cmd

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

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

Hello World!

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

そう、 .NET Core はクロスプラットフォームなのです ✨✨✨

--

--