【マルチモニタ】モニタ配置を記憶して切り替えられるソフト「MultiMonitorTool」

# はじめに
モニタを3枚以上使っている、かつモニタを2枚以上別デバイスで共有している人向けの需要が薄いであろう記事です。

## 環境
自宅ではモニタを4枚使っていて、それぞれメインモニタ、サブモニタ１、サブモニタ２、サブモニタ３とします。
メインPCでは全てのモニタを使用、PS5ではメインモニタを使用、サブPCではメインモニタとサブモニタ１を使用しています。

### 前座
メインPCとPS5を同時に使用すると、PC側ではメインモニタは接続されている扱いなので、メインモニタに表示されているものは見えなくなってしまいます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/335169/bc9a2da8-a2e3-7983-128b-896aba284224.png)

この場合の解決方法は簡単で、win+Pのショートカットで「セカンドスクリーンのみ」を選択すればPCからの出力はサブモニタのみになります。
powershellで実行したい場合は`DisplaySwitch 4`を実行すればよいです。

### 本題
さてそれでは本題ですが、メインPCとサブPCを同時に使っている場合です。
下記の図のようにサブPCではメインモニタとサブモニタ１を使い、メインPCではサブモニタ２,サブモニタ３を使っています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/335169/5bb36fef-a722-5507-c53d-bd049c0cfb3a.png)

この場合にはメインPC側でサブ１とメインモニタの接続を切りたいところですが、それをするには設定画面を開いて一つずつ切断する必要があります。
更にメインモニタをメインディスプレイにしている場合は先にサブ２かサブ３をメインディスプレイに設定してからでないとメインモニタを切断できません。

流石に毎回それをやるのは面倒くさすぎるので何か方法はないだろうかと探したところ見つけたのが「MultiMonitorTool」でした。

# どんなソフト？
マルチモニタの管理を行えるソフトです。
モニタ配置の保存、画面オフ、モニタの無効化等を行えます。
概要に関してはフリーソフト100さんを見るのが良いと思います。
[MultiMonitorTool のダウンロード・使い方 - フリーソフト100](https://freesoft-100.com/review/multimonitortool.html)

公式サイトには各種コマンドが乗っているのでこちらも目を通しておくと良いと思います。
[Enable/disable/configure multiple monitors on Windows](https://www.nirsoft.net/utils/multi_monitor_tool.html)

このソフトはコマンドがかなり充実しているのでバッチファイル化して一括でディスプレイ設定を変えることが可能…なのですが
少々癖が強く普通に使っていると詰まることがかなり多そうなので実際に使っているスクリプトを使用して解説していきます。

ただ使用しているモニタ、PCスペックなどによってかなり差が出ると思われるので参考程度にしたほうが良いとは思います…

また、このソフトとDisplaySwitchでの拡張やセカンドスクリーン等との併用は出来ません。[^1]
[^1]:DisplaySwitchの切断とMultiMonitorToolでの切断は違うっぽい？のですがよくわかりません…

# スクリプト

### サブ１とメインモニタの接続を切るスクリプト
まず最初にサブ１とメインモニタの接続を切るスクリプトですが、以下になります。

``` ps1:DISPLAY3とDISPLAY1の画面サイズを0にする（Width=0 Height=0）ことによって切断している
S:\Programs\multimonitortool\MultiMonitorTool.exe /SetMonitors "Name=\\.\DISPLAY3 Primary=0　`
BitsPerPixel=32 Width=0 Height=0 DisplayFlags=0 DisplayFrequency=60 DisplayOrientation=0　`
PositionX=-1920 PositionY=0" `
"Name=\\.\DISPLAY1 Primary=0 BitsPerPixel=32 Width=0 Height=0 DisplayFlags=0　`
DisplayFrequency=60 DisplayOrientation=0 PositionX=0 PositionY=0"
```

長ったらしいですが大事なのは`/SetMonitors`と`Width=0 Height=0`です。
`/SetMonitors`はモニタごとに設定を変更するコマンドです。
公式サイトを見ると変更したい項目だけ記載すれば良さそうな感じですが、すべての項目を埋めないと動きませんでした。[^4]
[^4]:おま環かもですが…

それを使ってNameが\\.\DISPLAY3であるモニタと\\.\DISPLAY1であるモニタの解像度を0にすることでそのモニタを非表示にしています。
disableというモニタを無効にするコマンドもあるのですがそちらを使うとどうもうまくいかなかったのでこの方法でやっていますが、disableがうまく行くならそっちでやったほうがキレイで良いと思います。

### すべてのモニタに接続するスクリプト
次にすべてのモニタに接続するスクリプトです。

```
S:\Programs\multimonitortool\MultiMonitorTool.exe /setmax "MONITOR\IOD1904\{4d36e96e-e325-11ce-bfc1-08002be10318}\0023"
S:\Programs\multimonitortool\MultiMonitorTool.exe /setmax "MONITOR\GSM5AB8\{4d36e96e-e325-11ce-bfc1-08002be10318}\0006"
S:\Programs\multimonitortool\MultiMonitorTool.exe /enable "MONITOR\GSM5AB8\{4d36e96e-e325-11ce-bfc1-08002be10318}\0026"
S:\Programs\multimonitortool\MultiMonitorTool.exe /setmax "MONITOR\GSM5AB8\{4d36e96e-e325-11ce-bfc1-08002be10318}\0026"
S:\Programs\multimonitortool\MultiMonitorTool.exe /setmax "MONITOR\EVE0001\{4d36e96e-e325-11ce-bfc1-08002be10318}\0024"

Start-Sleep 1

S:\Programs\multimonitortool\MultiMonitorTool.exe /SetPrimary "MONITOR\EVE0001\{4d36e96e-e325-11ce-bfc1-08002be10318}\0024"

Start-Sleep 1

S:\Programs\multimonitortool\MultiMonitorTool.exe /LoadConfig "S:\Programs\multimonitortool\extend.cfg"
```

ここで使っているsetmaxですが、これは対象のモニタの解像度をそのモニタの最大解像度にするというコマンドです。
前述のSetMonitorsで0にした解像度をここで戻すことで接続するようにしています。[^2]
[^2]: こちらもdisable、enableで事足りるならそっちを使ったほうが良いと思います。

また、こちらではディスプレイの指定方法をNameではなくMonitorIDにしていますが、これも何故かNameで指定したら上手く行かなかったのでこうしています。

「MONITOR\GSM5AB8\~\0026」についてはenableをした後にsetmaxしていますがこれも意図して書いたもので、このモニタはこう書かないと何故か動きませんでした…

Start-Sleepで1秒停止した後にSetPrimaryを使ってEVE0001をメインディスプレイにしていますが、ここで停止を挟まないと上手くメインディスプレイが切り替わりませんでした。[^3]
[^3]:EVE0001は画面の切り替わりが遅いのでそれが原因ぽいです

LoadConfigというのはモニタの配置などを読み込むコマンドです。
MultiMonitorToolでディスプレイ設定をするとモニタ配置が初期化されてしまうので、予め保存しておいたモニタ設定を読み込むようにしています。

### セカンドスクリーンのみに表示するスクリプト
最後にセカンドスクリーンのみに表示するスクリプトです。
```
S:\Programs\multimonitortool\MultiMonitorTool.exe /setmax "MONITOR\EVE0001\{4d36e96e-e325-11ce-bfc1-08002be10318}\0024"

Start-Sleep 1
S:\Programs\multimonitortool\MultiMonitorTool.exe /enable "MONITOR\GSM5AB8\{4d36e96e-e325-11ce-bfc1-08002be10318}\0026"
S:\Programs\multimonitortool\MultiMonitorTool.exe /setmax "MONITOR\GSM5AB8\{4d36e96e-e325-11ce-bfc1-08002be10318}\0026"

S:\Programs\multimonitortool\MultiMonitorTool.exe /disable "MONITOR\EVE0001\{4d36e96e-e325-11ce-bfc1-08002be10318}\0024"

Start-Sleep 1

S:\Programs\multimonitortool\MultiMonitorTool.exe /LoadConfig "S:\Programs\multimonitortool\second.cfg"
```

ここがかなり難関だったのですが、「MONITOR\GSM5AB8\~\0026」に対してsetmaxやenableを行っても何故かEVE0001に接続されるというよくわからない現象が発生していました。

なので無理やりの解決策として、
EVE0001に接続 →「MONITOR\GSM5AB8\~\0026」に接続（ここでも一時停止しないと上手く行かなかった）→ EVE0001を切断 → LoadConfigで配置設定
という手順を踏んでいます。

# まとめ
使いこなすのは難しそうですが、薄い需要に対してやりたいことが出来る貴重なソフトでした。
上手く動かないときはとりあえず`Start-Sleep 1`を挟んで置けばいいんじゃないかなぁって感じですかね…

今回の使用方法以外にもマルチモニタを使ううえで便利な機能が入っているのでモニタがいっぱいある人は一回見てみて損はないソフトだと思います。