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

joni2nja

Joni 【ジョニー】

Posted on September 20, 2019

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

This post originally appeared on Medium


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

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

Visual Studio Code

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

.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 ではなく 複数形 TargetFramework s (語尾に「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 はクロスプラットフォームなのです ✨✨✨

💖 💪 🙅 🚩
joni2nja
Joni 【ジョニー】

Posted on September 20, 2019

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related