This post originally appeared on Medium
VS Code リモート開発で .NET Framework の .exe をビルドしてみた
Linux/Mac環境で .NET Framework プロジェクトをビルド可能に~

以前 Twitter で見たのですが、Linux/Mac 環境でフル .NET Framework をターゲットし、ビルドができるらしい。
Muhammad Rehan Saeed@rehansaeeduk
You can now target and build full .NET Framework on Linux & Mac via Mono with official support. Add this package:
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" PrivateAssets="All" Version="1.0.0-preview.2" />
#dotnet #dotnetcore
github.com/Microsoft/dotn…13:11 PM - 02 Jun 2019
.NET Framework Targeting Pack Nuget Packages (Preview)
できるとのことなので、Linux マシンで普通にビルドしても面白くないので、今回は Visual Studio Code Remote Development(リモート開発)を使って、ビルドして検証してみたいと思います。
まずは VS Code を起動し、 F1
押下、コマンドを打ちます。 rem ad
という風に必要最低限の文字列を打つだけで検索結果がヒットしますので、凄く便利です。

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

Reopen in Container
を選択します。

そして、開きました。
左側は Windows Terminal で docker events
コマンドの結果をリアルタイムで表示しています。右側は VS Code リモート開発の準備ができた画面です。
VS Code の Terminal で dotnet new console
を打って新規コンソールアプリケーションを作成します。

(高解像度画像を表示)
プロジェクトファイルを生成され、デフォルトで .csproj ファイルはこんな感じで作られます。

netcoreapp2.2
を削除して、 net48
に変更します。 net48
は .NET Framework 4.8 の TFM (Target Framework Monikers) です。
dotnet build
コマンドでビルドをしてみると、エラーです。

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

(高解像度画像を表示)
お~!(≧▽≦)
宣伝通り、ビルドできましたね!
.exe ファイルちゃんと生成されています!
NuGet サイトで Microsoft.NETFramework.ReferenceAssemblies
を覗いてみましょう。

.NET Framework 4.8 はもちろんのこと、さかのぼって古い .NET Framework 2.0 も対応?! これは凄くないですか!レガシーシステム向けでちゃんと Microsoft がサポートしているということですね。
はい、次!試しに、 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 で直接実行したらどうなるでしょう?

(高解像度画像を表示)
当然ながら、 .exe ファイルを Linux 上で直接実行できないよ~!
では、 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 で覗いてみましょう。

(高解像度画像を表示)
Linux 環境で .NET Core 2.2 の .dll を実行してみましょう!

(高解像度画像を表示)
Hello World!
実行できましたね。
Windows Explorer を起動します。

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

ENTERキー押下!これで Explorer で開いているディレクトリがカレントディレクトリとして設定され cmd を起動されます。
先ほどと同じコマンド dotnet RefAsm.dll
を実行します。

(高解像度画像を表示)
Windows でも実行できてますね!
そう、 .NET Core はクロスプラットフォームなのです ✨✨✨
Top comments (0)