HOME > ソフテックだより > 第379号(2021年6月2日発行) 技術レポート「Linux上でWindowsアプリケーション(C#)を動かす〜 MONOランタイムの利用 〜」

「ソフテックだより」では、ソフトウェア開発に関する情報や開発現場における社員の取り組みなどを定期的にお知らせしています。
さまざまなテーマを取り上げていますので、他のソフテックだよりも、ぜひご覧下さい。

ソフテックだより(発行日順)のページへ
ソフテックだより 技術レポート(技術分野別)のページへ
ソフテックだより 現場の声(シーン別)のページへ


ソフテックだより 第379号(2021年6月2日発行)
技術レポート

「Linux上でWindowsアプリケーション(C#)を動かす〜 MONOランタイムの利用 〜」

1. はじめに

私はWindowsアプリケーション開発を担当する機会が多い入社20年超の社員です。

Windows上で動作するUIアプリケーション開発を行う場合、.NET Framework実行環境上で動作させる.NETアプリケーションとして開発することは一般的になっていると思います。
開発ツールに「Microsoft Visual C#」を使えば、一般的なWindows上で動作するUIのアプリケーションを容易に作成できるため、私が業務で関わるシステムのPCアプリケーション開発でも.NETアプリケーション(C#)として開発するケースは多いです。

ソフテックだより本号では、マルチプラットフォーム対応の一例として、Linux環境(今回はRaspberry Pi Desktop)で「MONO」実行環境(ランタイム)を利用して.NETアプリケーションを動かす方法についてご紹介させていただきます。

2. MONOとは

「MONO」はオープンソースの.NET Framework互換フレームワークで、コンパイラ(C#)、実行環境(ランタイム)、標準ライブラリともECMA標準の規格に基づいて実装されています。.NETクロスプラットフォームのアプリケーション開発が可能なため、Windows上(Visual C#)で開発した.NETアプリケーションをMONOランタイム上で動作させることができます。

既にWindows上で稼働させているPCアプケーション(C#)と同等のUI機能を提供するソフトウェアをLinux上でも運用したい場合には、既に存在するWindowsアプケーションのプログラムコードを最大限流用して対応するアプローチが可能なため大きなメリットを感じます。

また、「MONO」で提供されるC#統合開発環境(IDE)である「MONO Develop」を使えば、Microsoft Visual C#で作成したプロジェクトをビルドしてLinux環境固有の問題で動作しない場合などにデバック実行することができる点もメリットとして挙げられます。
「MONO Develop」はC#統合開発環境で下記に示すプラットフォームに対応しており、複数のプラットフォーム環境で動作するデスクトップアプリケーションや Web アプリケーションのクロスプラットフォーム開発ができます。

■MONO Develop 特徴
・マルチプラットフォーム
Linux、Mac iOS、Microsoft Windows、BSD、等

・マルチ開発言語サポート
C#、F#、VB.NET、ASP.NET、Vala、等

・その他 機能
GTK# (UIデザイナ)
NUnit(単体テスト統合機能)

3. Linux (Raspberry Pi Desktop)上で.NETアプリケーションを動かす方法

ご説明したようにMONO実行環境(ランタイム)で、Windows上で開発(C#)したアプリケーションを動作させることができます。
Linux環境にMONOランタイムをインストールして、MONOランタイム上でアプリケーション(*.exe)を実行させるだけですので、とても簡単です。

以下、Raspberry Pi Desktop上でWindowsアプリケーション(C#:TestGuiApp.exe)を動かす場合の対応例をご説明します。

■MONOのインストール
ターミナルで下記コマンド実行し、MONOをインストールます。
※ .NETアプリケーションを動かすだけであれば「MONO Develop」はインストール不要
#事前準備
$ apt list --installed | grep dirmngr

#以下のコマンドでキーを更新します
$ sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF

#以下のコマンドで、apt-getリポジトリにMonoのリポジトリを追加します
$ echo "deb http://download.mono-project.com/repo/debian wheezy main" | sudo tee /etc/apt/sources.list.d/mono-xamarin.list

#リポジトリのリストを更新します
$ sudo apt-get update

#インストール
sudo -E apt-get install mono-complete

#MONO Develop インストール ※ C#アプリを動作させるだけであれば不要
$ sudo apt update
$ sudo apt install mono-devel

■MONO実行環境(ランタイム)で.NETアプリケーションを動かす
ターミナルで"mono ****" (****:実行ファイルパス)コマンドにより、MONOランタイムで.NETアプリケーションを起動できます。

(例) home/pi/Work/TesGuiApp/TestGuiApp.exe を実行する場合
#事前準備
$ mono home/pi/Work/TestGuiApp/TestGuiApp.exe

以下、Linux環境(Raspberry Pi Desktop)とWindows 10環境で実行した時の画面イメージになります。

<Raspberry Pi Desktopでの表示>
Raspberry Pi Desktopでの表示

<Windows 10での表示>
Windows 10での表示

■ショートカットによる実行ファイル起動
ショートカットファイル(ファイル拡張子: *.sh)を作成すれば、ターミナルでコマンドライン実行ではなく、ショートカットから起動できます。

(例) home/pi/Work/TesGuiApp/TestGuiApp.exe を実行するショートカットファイル
(実行ファイルと同一階層にアイコン用のTestGuiApp.jpgあり)
[Desktop Entry]
Type=Application 
Exec=mono /home/pi/Work/TestGuiApp/TestGuiApp.exe
GenericName=Test GUI Application
Path=/home/pi/Work/TestGuiApp
Comment[ja_JP]=Test GUI Applicattion
Icon=/home/pi/Work/TestGuiApp/TestGuiApp.jpg
Terminal=false

プロパティ


4. Linux (Raspberry Pi Desktop)上で確認できたMONOランタイムによる.NETアプリケーション互換動作

MONOランタイムで.NET標準クラス、C#コードがどこまで互換性をもって動作するかテスト用アプリケーションで確認してみました。確認した結果の注意点については後述しますが、私が業務で利用する機会の多い.NET標準クラスはWindows上で動かした時と遜色ない操作感/意図した処理ロジックで動作することが確認できました。

(1) 画面UI (画面デザイナ構築内容)
下記、画面UI周りの動作で問題なく動きました。

・標準コントロール系
Form、Label、TextBox、Button、ComboBox、NumericUpDown、DataGridView、PropertyGrid、Panel、GroupBox

・ユーザーコントロール

・コントロール派生クラス
Panelクラス派生クラスのOnPaintBackgroundオーバライドによるオーナードロー
(例) 子コントロール(TextBox/Button/DataGridView)の背景に影を表示する描画処理を記述
子コントロールの背景に影を表示する描画処理

DataGridViewのCellPaintingイベントによるオーナードロー
(例) 奇数列(Col1, Col3)の選択セルを橙色枠でセル表示する描画処理を記述
奇数列の選択セルを橙色枠でセル表示する描画処理

(2) 良く利用する.NET標準クラス
Windowsアプリケーション開発で良く利用する.NET標準クラスについて動作を確認し、下記クラスについて想定動作を確認できました。

・標準ファイル選択ダイアログ
OpenFileDialog、SaveFileDialog クラス

・UI補助機能 (タイマー、バックグラウンド処理)
Timer、BackgroundWorker クラス

・XMLファイル操作 (シリアライズ/デシリアライズ)
XmlSerializer クラス

・TCPサーバー/クライアント通信、UDP通信
TcpListen、TcpClient、UdpClient クラス

・SQL DBアクセス
SqlConnection、SqlCommand、SqlDataAdapter、DataTble クラス

(3) .NETライブラリ (C#)
C#でビルドしたライブラリ(参照設定に追加して利用)が提供するモジュールコール動作も想定通りに動作しました。
Windows実行ファイル(*.exe)と同様に実行ファイルと同一階層にライブラリファイル(*.dll)を置いておけば問題ありませんでした。

(4) 共有ライブラリ (C/C++)
C/C++でビルドした共有ライブラリ(DllImportで利用)が提供するモジュールコール動作ですが、当然、Windows上でビルドしたライブラリ(dll)はLinux上では動きません。I/F仕様(機能実装)が同一の共有ライブラリ(so)をLinux上でコンパイルしたものを使えば動きます。

(例) /home/pi/Work/TestLib.c をコンパイルして、libTest.so 共有ライブラリを作成する
# 共有ライブラリ作成
$ cd /home/pi/Work
$ gcc -shared -o libTest.so TestLib.c

(例) /home/pi/Work/TestLib.cpp をコンパイルして、libTest.so 共有ライブラリを作成する
# 共有ライブラリ作成
$ cd /home/pi/Work
$ g++ -shared -fPIC ./TestLib.cpp -o libTest.so

5. 注意点

Windows上で動作するアプリケーション(C#)をMONO実行環境(ランタイム)を利用してLinux上で動作させる場合の注意点を下記に挙げます。

(1)ファイルパスのルールが異なる
Linux環境ではファイルパスのルールがWindowsと異なります。ファイルパスをプログラムコードで対応するケースは多いと思いますので、Linux環境で正常動作しない原因となります。Linux環境で扱うファイルパスで対処が必要な点として下記のものがあります。
・"C:\"のようなトップフォルダ(ディレクトリ)の前に"A:"〜"Z:"のドライブ名が無い
・大文字と小文字が区別される
・サブフォルダ区切り文字も"\"→"/"と異なる

(2) COMコンポーネントはWindows固有の機能なので動作しない
COMコンポーネントの代替プログラム実装の置き換えが必要

(3) Windows APIのリフレクションによるコールもWindows固有なのでエラーになる
例えば、FTPクライアント処理をwininet.dllを使って機能実装していた場合

(4) BCF(基本クラス・ライブラリ)と呼ばれる.NET標準クラスは問題なく動作するが、非サポート/完全互換していないクラス利用時はプログラムコードを動作するように置き換えが必要

(5) 共有DLL(C/C++)を利用時は、対処が必要になる
同I/F仕様の共有DLLをLinux環境でコンパイルしたライブラリ(*.so)に置き換える
共有DLLと同じI/F実装処理をC#プログラムコードに置き換える

(6) 日本語の表記が文字化けしたり、フォントの問題で画面表示レイアウト崩れる場合がある
代替フォントをインストールする、表示が崩れるフォントを代替フォントに変えてビルドし直すことで対策がとれる

(例) Linuxにフォントをインストールする
#MS fontsを入れる
$ sudo apt-get install msttcorefonts

6. さいごに

今回ご紹介させていただいたMONOランタイムを利用することで、Windows上で動作させているアプリケーション(C#)を容易にLinux環境でも動作させられるアプローチが取れることをご理解いただけたのではないでしょうか。
特にWindowsアプリケーション(C#)として開発したソフトウェアをLinux環境で運用させたいケースには、注意点で挙げさせていただいた対処を行うことで対応ができるので、オープンソースのライブラリ利用をご理解いただいた上でMONOランタイムを利用する方法は選択肢として有用だと思います。
また、Linux環境で動作するUIアプリケーション開発する際に、Linux環境用の開発プラットフォームを使った開発経験はないが、Windowsアプリケーション開発(C#)の開発経験はお持ちの方が対応されるケースも「Microsoft Visual C#」で開発してMONOランタイムを利用して動かすといったアプローチも可能です。

尚、クロスプラットフォーム開発のフレームワークに.NET Coreがあります。こちらは画面UI周りの.NET標準クラス(Windows Formクラス)がサポートされていなかったのですが、.NET Core 3.0以降から対応されるようになり、開発環境:Visual Studio 2019では.NET Core Windows Formsアプリケーションのフォームデザイナが実装されるようになりました。Windowsアプリケーション(C#)と全く同じ感覚で開発ができるようになりましたので、機会があればクロスプラットフォーム開発をテーマにソフテックだよりで取り上げさせていただくかもしれません。

本ソフテックだよりでご紹介させていただいた内容がシステム検討の際などに参考になれば幸いです。

(M.S.)

[参考サイト]
https://www.mono-project.com/
… MONO公式サイト
https://www.mono-project.com/docs/getting-started/install/linux/
https://www.mono-project.com/download/stable/
… Linux Mono インストール
https://github.com/mono/mono/tree/main/mcs/class
… GitHubリポジトリ:MONO対応クラスライブラリ

関連ページへのリンク

関連するソフテックだより

ページTOPへ