Tatsu still writes something... Fourth season

これからも私はなにかをしてなにかを書く

極めて雑で限りなくいい加減な.NET5へのWindows Formsアプリの移植

今週のお題「自由研究」ということで今日やった自由研究のことでも書いてみる。相変わらず自作ソフトネタだけど。

このソフトの明日のために

.NET Frameworkは4.8でWindowsコンポーネントとしてメンテナンスモードに入り、.NET Coreから発展したクロスプラットフォームの.NETが後を継ぐということになった。そして、LTSとなる.NET 6からいよいよ本流となるということで今後のWindowsの機能を使うに当たっては.NETに移行する必要がありそうだ(使うかどうかはわからんけど)。

C#もまた.NET Frameworkではバージョン7.3までしか使えないので最新のC#を使うとなると.NETに移行する必要がある(最新のC#の機能を使うかどうかはわからんけど)。

仕事でもし.NETに当たったら否が応でもこの.NET移行の事態にぶつかることになるのだが、実は自分個人でも既にぶつかってしまっているのである。そう、MulSyncである。なまじVectorベクターソフトニュースで紹介されたこともあり、中途半端をかますわけにはいかなそうである。

というわけで夏休みの自由研究として今使える.NET5へのMulSyncの移植を手持ちのVisual Studio 2019 Version 16.11で試しにやってみたのでどんなことやったかをなんかの役に立つかもしれないので書く。あくまでもお試しだし、.NETランタイムのサポート期限もあるので作ったものを公開するわけではないが。

やってみる

.NET Frameworkでのやり残しをなくす

.NETでWindows Formsといっても.NET Frameworkのやつの延長なので、まずは.NET Framework 4.8でちゃんとコンパイルできて動くことを確認する。MulSyncは.NET Frameworkの機能だけを使っていたので問題なし。ここでサードパーティーのライブラリとか、.NETでサポートされないクラスとか使っていたらその辺の確認が入ってくるのだが、それはそういう状況に当たったらやるということで。

ついでにというか、地味に大事なのだがプロジェクトに入ってないソースなどのファイルや冗長な記述の整理を行う。これを行っておかないとあとで面倒なことになるのでここでやっておきたいというものである。実際気を付けてても冗長な記述で戸惑うことになったし。

.NETでプロジェクトを作る

.NET Frameworkでの準備が終わったら.NET Frameworkの時と同じレイアウトになるように.NETのWindows Formsソリューションとプロジェクトを作る。とりあえず、ここは作るだけ。

.NETのプロジェクトにファイルをぶち込む

プロジェクトを作ったら.NET Frameworkで使っていたファイルを.NETのプロジェクトディレクトリに同じディレクトリ構成でコピーする。.NETのビルドシステムはプロジェクトファイルのフォルダ内にあるファイルを認識してくれるので、とりあえずこれでOK。ファイル認識は自動で行われるので、ごみをコピーするとそれも取り込んでコンパイルエラーなどを起こすのでごみは削除する必要がある。.NET Frameworkの時点でごみを掃除しろと言ったのはこの為である。

プロジェクトのおぜん立てを行う

ここまでの段階ではスタートアップオブジェクトとか、アイコンとかの設定を行ってないのでその辺を.NET Frameworkのプロジェクトから書き写しておく。あと、リソースとかもちゃんと入っているかどうか確認しておく。

バージョン情報についてはプロジェクトファイルの編集で<PropertyGroup>要素の中に<GenerateAssemblyInfo>false</GenerateAssemblyInfo>と書いておけば.NET Frameworkで使っていたAssemblyInfo.csが使えるので書いておく。

レッツコンパイル

ここまでおぜん立てが終わったらコンパイルする。.NET Frameworkのビルドシステムでビルド通ってたけどビルドが通らないところがあったら直す。なんでこんなの通ってたんだというのがあろうが、何があろうがとにかく直す。

動け、動け、動け、動け

コンパイルが通ったら動かしてみる。今回はお試しということでそれっぽく表示されて動いたという程度で済ませたが、実戦では見た目から挙動まで.NET FrameworkWindows Forms(+Visual Studio)と.NETのそれでは違うことがあるので、テストすることになる。テスト頑張ってください。

ちなみにMulSyncではメイン画面だけフォント設定が違ってた。まあ、見た目だけで済んだので今回はフォントなんて飾りなんですということにしておく。けど、実際フォント何使うのがいいんだろう。いまさらMSゴシックでもないし、豪華な食堂できれいでうまい食事食べてるくせに美的センスがアレな日本のマイクロソフトが好きそうなほげほげUIはどれもいまいちだし。でブチ切れてMeiryo UIも大っきらい!!作って面白くも面倒なことになったのだがそれは別の話。

人様に見せるなら

.NETのプロジェクトではビルドしてbinディレクトリからリリース版をコピーするには不要なファイルがあったりするのでビルドの発行で必要なファイルだけをまとめ上げて、これを配布することになる。

とりあえず、今回はフォルダへの発行を選んで、すべての設定を表示をクリックしてプロファイル設定を出して試してみた。配置モードは.NETランタイムのバージョンアップを考えるとフレームワーク依存になるが、ターゲットランタイムを移植可能にして、x86、x64、Arm64全狙いにするか、ターゲットランタイムを固定して単一ファイル配布にするかは悩みどころだ。

Arm版Windowsってどうなんだろう。ダメダメだったらx64決め打ち単一ファイル配布がユーザーにとって楽そうだが。

結果

今回の結論としては、.NET Frameworkのビルドシステムから.NETのビルドシステムに移行してビルドシステム間のギャップを埋めることで、プログラムの変更なくある程度動いたので.NETでもWindows Formsは使えそうだというところである。

使えるではなく、使えそうにとどめたのはいくつか理由がある。

Windows Forms自体がいい加減古い

古き良き(?)VBのころからの流儀を引き継いでいるのでViewというかUIとロジックが癒着しやすくテストしにくいなどいろいろとWindows Forms自体が古いのは否めないところである。後発のフレームワークがある程度は問題を解決している上、WinUIとか.NET MAUIとか更なるフレームワークが待ち受けている状況ではデスクトップの.NETは.NET6で横一線のスタートとなるので.NETを使うのであればそれらも考慮に入れたいところである。

どこまでサポートされるかが分からない

Windows Forms自体が古いことと相まって今後のWindowsの機能を何らかの手でどれだけサポートされるのが分からないということがある。Project reunionことWindows App SDKというものがあるがWindows Formsのサポート度次第ではWindows Formsを.NETでやらずに.NET Frameworkにとどまる程度でいいやという結論になる可能性がある。.NET FrameworkがVB6とそのランタイムのような状態になったらいろいろなデメリットが出るというリスクはあるが。

そもそも、Visual Studio 2019 Version 16.11の.NETのWindows Formsデザイナーの出来もなんか怪しいところがあるのを考えるとサポート面に関しては不安はぬぐえない。そう思ったのは、MulSyncは一応日本語と英語対応なのだが、フォームのLanguageプロパティを変更して編集する言語リソースを変えようとした時にLanguageプロパティは変わったが、ラベルのテキストなどが変わらないということがあったという経験からきている。

それでもWindows Formsはそこにいる

今年に入って速度稼ぐ必要がある仕事を行ったが、こういうワークロードではべたな作りのおかげでDirect 2DなどのAPIとの連携ができて速度稼げたので、C/C++が高級アセンブラといわれるようにC++との組み合わせで高級Win32とか、高級COMとかといった感じになるのかなと個人的には思っている。

まあ、ビジネスはもっと生産性の高いのがあったらそっちになるだろうけど。

そんな、所です。