.NET6でSerialPortコンポーネントを使えるまで

カテゴリー: ソフトウェア  タグ:

ずっと.NETframeworkを使ってました。簡単なアプリが多いのでいまでも支障はないのですが、WPFにするスキルもなくWFAを使い続けようと思っていた矢先に、.NETframeworkは長期サポート外ということが分かり、それではLTS版の.NET6にアプリを移行してみたらどうか、とやってみたらSerialPortがうまくいかないので解決するまでの覚書。

.NET アップグレード アシスタントが存在する。

永らく使ってたVisualStudio2019は.NET6.0に対応してないので、VisualStudio2022communityをあらたにインストール。

私の場合、アプリはDUTとPCは仮想シリアルでつなぐといった簡単なものが多く、アプリ規模が小さいので、だいたいは移行アシスタントで一発変換できました。

projectの.NET6への移行はWindowsのTerminal(PowerShell)で変換アプリを実行

Terminalで以下のコマンドで「.NETアップグレードアシスタント」をインストール

dotnet tool install -g upgrade-assistant

インストールできたら、目的の.slnファイルがあるフォルダに移行して、アップグレードのチェックと実行を行います。説明サイトはここ

upgrade-assistant analyze 〇〇〇.slnを実行してエラーを見ておき、

問題なければ

upgrade-assistant upgrade 〇〇〇.slnを実行する

すべて1を選択して変換終了。わたしのアプリの多くはチェック時に説明サイトと同じワーニングのほかにもう一つ、「Default font in・・・」がでています。

[11:24:18 WRN] Default font in Windows Forms has been changed from Microsoft Sans Serif to Segoe UI, in order to change the default font use the API - Application.SetDefaultFont(Font font). For more details see here - https://devblogs.microsoft.com/dotnet/whats-new-in-windows-forms-in-net-6-0-preview-5/#application-wide-default-font.
[11:24:18 WRN] HighDpiMode needs to set in Main() instead of app.config or app.manifest - Application.SetHighDpiMode(HighDpiMode.<setting>). It is recommended to use SystemAware as the HighDpiMode option for better results.

スクリーンとFont関連らしいのでとりあえずスルーして変換を実行しています。

私の作成したアプリではSerialPort以外はコンバートOK

いくつか試したアプリは大体大丈夫でした。VisualStudio2022で.NET6で問題なくコンパイル、実行、デバッグが出来ます。

SerialPortアクセスでエラーがでる。.NET6では標準で組み込まれてない

SerialPortコントロールを使ったアプリだけは、コンバートしたプロジェクトはビルドは通るのですが、実行するとSerialPortで実行エラー。

System.IO.Portsを組み込む

あまり情報がないのでChatGPTで問合せ。こんな回答です。なるほどなるほど・・・

そこから先は、わりとすらすらと解決しました。

要はツールボックスからは無くしたが、System.IO.Portsに置いてあるので、自分でコントロールを追加してくれ、ということらしい。

NuGetパッケージの管理で「System.IO.Ports」を組み込む

ツールボックスに表示されないので、これは、プロジェクト毎にやらないといけないので結構面倒ですが、いずれ.NETに復活することを期待しておきます。

パッケージの追加は何通りかあるようですが、私はソリューションエクスプローラーを右クリックして「NuGetパッケージの管理」から、System.IO.Portsを検索してインストールしました。

組み込んだ時点で、ソースファイルにusing System.IO.Ports記述が自動的に付加されました

既存の.NetframeworkのSerialPortを使ったコードに少し付けたし

名前空間、クラス宣言とインスタンス、受信イベントハンドラの記述を追加します。まずは名前空間。

using System.IO.Ports;

以下は.NETframeworkのSerialPortクラスを配置して「SerialPort1」という名前のコントロールがすでに配置してあるアプリを前提にしています。変換後も既存のSerialPort1コンポーネントが残っているのでトラブルを避けるためにも一旦削除して、残ったコードに以下を追加しました。

まず宣言。

System.IO.Ports.SerialPort serialPort1;

そのクラスのインスタンス作成時に下記を追記します。私の場合はすべてFormクラスをそのまま使うので、Formの「InitializeComponent();」行の下に追加します。

serialPort1 = new System.IO.Ports.SerialPort(new System.ComponentModel.Container());

そして、イベントハンドラの記述。

serialPort1.DataReceived += serialPort1_DataReceived;

これで、.NetFrameWorkのSerialPortクラスと同じ動作になりました。

「.NETframeworkまだ使ってんの?」なんて言われるまえに(言われない確率は高いですが・・・)対策できるとこはしておこう、という単純なことでした。

お気軽にコメントをどうぞ。

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)