仮想シリアル(COM) ポートドライバ「com0com」によるシリアル通信

# はじめに
2年前に作成したシリアル通信を使用するアプリケーションの改修をすることになった。その時より新しいPC(Windows 7 64bit)に変わっている。現在では、Windows 10 64bitになっています。

最近のPCにはCOMポートが無くなってしまっているため、仮想シリアル(COM) ポートドライバで有名なフリーソフト「[com0com](https://ja.osdn.net/projects/sfnet_com0com/)」を使用する。

「com0com」は2つの仮想のCOMポートをクロスケーブルで接続したように見せかける仕組み([ループバック](http://www.sophia-it.com/content/%E3%83%AB%E3%83%BC%E3%83%97%E3%83%90%E3%83%83%E3%82%AF))となっているため、ポートが必要な分だけペアで作成する。

【2023/02/25追記】
久しぶりに「いいね」が付くと、記事を見直すきっかけになります。Qiitaは履歴が残るので Windows 7 については削除するのと、Intel Mac と Parallels Desktop for Mac 内の Windows 11で確認した結果を報告します。

# com0comのインストール
ドライバ警告回避方法について、2つの方法を提示します。
自分の場合、特殊な環境「Intel Mac と Parallels Desktop for Mac 内の Windows 11」だったため、その1 の方法では回避できなかったため、その2 の方法で回避することができました。

## com0comのダウンロード
2017/07/13にデジタル署名付きの[com0com-3.0.0.0-i386-and-x64-signed.zip](https://sourceforge.net/projects/com0com/files/com0com/3.0.0.0/)が公開されたのでダウンロードする。

## ドライバ警告回避方法 その1
インストール後、デバイスマネージャを開いて、該当するドライバに警告が出ていないか確認してください。
警告が出ている場合は、ドライバの更新(Windows Update経由)※で署名済みの最新ドライバを入手することができます。(Microsoft Windows Hardware Compatibility Publisher署名に切り替わります)

※ドライバの更新は該当デバイスを右クリック→ドライバーの更新でWindowsUpdate経由で行うことができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12275/402f153e-9b80-b83f-f68b-8766fe1ac384.png)
※Windows 10 20H2でドライバーを更新したい場合はWindows Update上で操作する必要があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12275/7dc0abda-46b7-f1d6-43d8-65aec4e14a37.png)

参考: 

- 次のエディションではインストーラの実行のみで認識されました
    - Windows 10 Home 20H2
    - Windows 10 Pro 2004
- 次のエディションではドライバの更新が必要でした
    - Windows 10 Pro/Home 1909
- 署名は[Windows Compatible Products List](https://partner.microsoft.com/en-us/dashboard/hardware/search/cpl)からcom0comと入力すると確認できます

## ドライバ警告回避方法 その2
下記の動画に則った方法になります。

<iframe width="560" height="480" src="https://www.youtube.com/embed/Z8jFWQYxSNc?start=125" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

準備として、com0comの署名済みドライバーが7z形式で圧縮されているため、7-ZIPを[ダウンロード](https://sevenzip.osdn.jp/)してインストールしてください。

### 動画の方法
1. [pete.akeo.ieのサイト](https://pete.akeo.ie/2011/07/com0com-signed-drivers.html)から「[署名済みの 2.2.2.0 com0com ドライバー](https://files.akeo.ie/blog/com0com.7z)」をダウンロードします。
2. 7-ZIPで展開します。
3. x64フォルダ内の`com0com.inf`ファイルを右クリックメニューから「インストール」を選択します。
4. デバイスマネージャを開いて、ドライバの警告が解消されていることを確認します。

自分の場合には動画の方法では解決しなかったため、記事の方法で回避しました。
もしかしたら管理者権限でなら解消できたかも知れませんね。

### 記事の方法
[サイトの記事](https://pete.akeo.ie/2011/07/com0com-signed-drivers.html)通りにしました。

1. [pete.akeo.ieのサイト](https://pete.akeo.ie/2011/07/com0com-signed-drivers.html)から「[署名済みの 2.2.2.0 com0com ドライバー](https://files.akeo.ie/blog/com0com.7z)」をダウンロードします。
2. 7-ZIPで展開します。
3. x64フォルダ内の`setupc.exe`を管理者権限で開きます。
4. コマンドプロンプトが開くので、「install - -」と入力します。 
5. デバイスマネージャを開いて、ドライバの警告が解消されていることを確認します。

# ポート名の変更
3.0.0.0のセットアップ画面の先頭に「use Ports Class」のチェックボックスが追加されています。これは空いているポートを自動で設定する機能です。
[ASUS Vivotab note 8でGPSソフトが使えた話（無料カーナビ化に挑戦）](http://gadgety.hatenablog.com/entry/asus-vivotabnote8-gps)

3.0.0.0版のセットアップ画面(赤枠が追加)
![com0com3000.png](https://qiita-image-store.s3.amazonaws.com/0/14053/8c5b31c1-d953-d4ce-d940-404bd689dbab.png)


**※以降の記事の画像は2.2.2.0版のセットアップ画面になります。**

インストール直後ではCOMポートの名前が「CNCA0」と「CNCB0」になっているので、「COM11」と「COM12」などに変更します。
[スタート]→[すべてのプログラム]→[com0com]→[Setup]を起動します。

「CNCA0」と「CNCB0」の名前を「COM11」と「COM12」などに変更して「Apply」ボタンをクリックします。
![image](https://qiita-image-store.s3.amazonaws.com/0/14053/3e549d36-d1ab-1dfe-77de-15919389f466.png)

上述のセットアップ画面で変更できるようになったのでコマンドプロンプトによる方法は不要となるのですが、念の為に提示しておきます。

[スタート]→[すべてのプログラム]→[com0com]→[Setup Command Prompt]を起動します。
[list]コマンドで現在のポート名が確認出来ます。
[change CNCA0 PortName=COM11]コマンドでポート名を変更出来ます。
[change CNCB0 PortName=COM12]コマンドでポート名を変更出来ます。
[仮想シリアル(ＣＯＭポート)ドライバ(ツール/ソフト) 設定方法/使用方法(使い方)](http://nonsoft.la.coocan.jp/Link/Null-Modem.html)

```bash:ポート名変更
Enter 'help' to get info about usage of Setup for com0com.

command> list
       CNCA0 PortName=-
       CNCB0 PortName=-
command> change CNCA0 PortName=COM11
       CNCA0 PortName=-
change CNCA0 PortName=COM11
Restarted CNCA0 com0com\port \Device\com0com10
       CNCB0 PortName=-
ComDB: COM11 - logged as "in use"
command> change CNCB0 PortName=COM12
       CNCA0 PortName=COM11
       CNCB0 PortName=-
change CNCB0 PortName=COM12
ComDB: COM12 - logged as "in use"
command> list
       CNCA0 PortName=COM11
       CNCB0 PortName=COM12
command>
```

# ポートの確認
## デバイスマネージャーによる確認
[コントロールパネル] - [ハードウェアとサウンド] - [デバイスとプリンター]にある「デバイスマネージャー」を開きます。
「com0com0」が追加されて警告マークが付いていないことを確認します。
![image](https://qiita-image-store.s3.amazonaws.com/0/14053/0b2fcc49-9b05-5b32-8fca-7b769ea40ef9.png)

## TeraTermによる確認
シリアル通信に使用できるターミナルソフト「TeraTerm」をダウンロードしてインストールする。
[Tera Termのダウンロード](http://forest.watch.impress.co.jp/library/software/utf8teraterm/)

メニューから「設定」の「シリアルポート」を選択する。ポートに「COM11」と「COM12」が表示されていることを確認する。
![image](https://qiita-image-store.s3.amazonaws.com/0/14053/a13d39c4-7981-ee48-5d51-5c0d74ba24cf.png)

# 送信内容の確認
「COM11」と「COM12」はクロスケーブルで接続したように見せかけるの方式となっているため、「COM11」で送信した値は「COM12」で受信される。

TeraTermにて「COM12」に接続すれば、アプリケーション側で「COM11」で送信した値がTeraTerm上の画面に表示される。

# ポートの追加
[スタート]→[すべてのプログラム]→[com0com]→[Setup]を起動します。
「AddPair」ボタンをクリックしてポートを追加します。
追加したCOMポートの名前が「CNCA1」と「CNCB1」になっているので、「COM21」と「COM22」などに変更して「Apply」ボタンをクリックします。
![image](https://qiita-image-store.s3.amazonaws.com/0/14053/4a6c0327-287f-9959-e199-f797550971d3.png)

![image](https://qiita-image-store.s3.amazonaws.com/0/14053/d3cde8b6-849f-8c1f-ccad-0e3b1e4886a2.png)

# Visual Studioのデバッグ時の注意
Visual Studioのデバッグ時に例外でアプリケーションが強制終了してしまう現象が発生

https://stackoverflow.com/questions/7996331/c-sharp-serialport-application-hangs-if-there-is-no-recipient-on-write-virtu

「enable buffer overrun」を有効化することで、通信エラーにならないが例外で強制終了することはなくなりました。

# 最後に
「com0com」はとても便利ですが、所詮は仮想ですので最終的な確認は本物のシリアルポートがあるPCでやりましょう。