multimonitortoolで三つのモニターをbatファイル使って自動化する

※batの知識がない投稿者です。
GPT使って全部書いてもらいました。
3日ほどかけたので記事にしてみようと思った次第。
***
#### 前提
■
```MultiMonitorTool.exe```は、
```C:\Tools\MultiMonitorTool```に
■
モニターの情報は```monitor_list.txt```として
```C:(適当なフォルダ)\```

モニターに関して
私の場合

私用時、左からAUS25A4,BNQ7FA3,GSM5ACDを使っており、BNQ7FA3がメインモニターです。
![スクリーンショット 2024-12-19 175043.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3298542/6b78d1e1-3085-07f0-e126-cbee5b9b73f5.png)

社用時、左からAUS25A4,GSM5ACDを使っており、BNQ7FA3が切断されて、AUS25A4がメインモニターです。
![スクリーンショット 2024-12-19 175212.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3298542/f8a61227-2e11-6a71-dd64-948d6c5a6049.png)

***
## 結論のコード

```bat
@echo off
chcp 932 >nul
title ディスプレイ切り替えメニュー
color 0A

REM --- 管理者権限を確認する ---
net session >nul 2>&1
if %errorlevel% neq 0 (
    echo 管理者権限が必要です。管理者として再実行します。
    powershell -Command "Start-Process -FilePath '%~0' -Verb RunAs"
    exit /b
)

REM --- モニター情報を取得 (最小化して非表示で実行) ---
echo モニター情報を取得中...
"C:\Tools\MultiMonitorTool\MultiMonitorTool.exe" /SaveConfig "C:(適当なフォルダ)\monitor_list.txt"

REM --- 1秒待機 (pingで待機) ---
ping -n 1 127.0.0.1 >nul

REM --- 変数展開を有効にする ---
setlocal enabledelayedexpansion

REM --- MONITOR1 (MONITOR\AUS25A4) の Name を取得 ---
set "MONITOR1=MONITOR\AUS25A4"
set "prev_line="
for /f "tokens=*" %%i in ('type "C:(適当なフォルダ)\monitor_list.txt"') do (
    set "line=%%i"
    echo !line! | findstr /C:"MonitorID=!MONITOR1!" > nul
    if !errorlevel! equ 0 (
        echo !prev_line! | findstr /C:"Name=" > nul
        if !errorlevel! equ 0 (
            REM 直接 Name= の行から \\.\DISPLAY1 を抽出
            for /f "tokens=2 delims==" %%a in ("!prev_line!") do set "DISPLAY_NAME1=%%a"
        )
    )
    set "prev_line=!line!"
)

REM --- MONITOR2 (MONITOR\BNQ7FA3) の Name を取得 ---
set "MONITOR2=MONITOR\BNQ7FA3"
set "prev_line="
for /f "tokens=*" %%i in ('type "C:(適当なフォルダ)\monitor_list.txt"') do (
    set "line=%%i"
    echo !line! | findstr /C:"MonitorID=!MONITOR2!" > nul
    if !errorlevel! equ 0 (
        echo !prev_line! | findstr /C:"Name=" > nul
        if !errorlevel! equ 0 (
            REM DISPLAY_NAME2 を格納
            for /f "tokens=2 delims==" %%a in ("!prev_line!") do set "DISPLAY_NAME2=%%a"
        )
    )
    set "prev_line=!line!"
)

REM --- MONITOR3 (MONITOR\GSM5ACD) の Name を取得 ---
set "MONITOR3=MONITOR\GSM5ACD"
set "prev_line="
for /f "tokens=*" %%i in ('type "C:(適当なフォルダ)\monitor_list.txt"') do (
    set "line=%%i"
    echo !line! | findstr /C:"MonitorID=!MONITOR3!" > nul
    if !errorlevel! equ 0 (
        echo !prev_line! | findstr /C:"Name=" > nul
        if !errorlevel! equ 0 (
            REM DISPLAY_NAME3 を格納
            for /f "tokens=2 delims==" %%a in ("!prev_line!") do set "DISPLAY_NAME3=%%a"
        )
    )
    set "prev_line=!line!"
)
REM --- モニター設定を表示を確認。 ---
set DEBUG=1

if %DEBUG%==1 (
    echo MONITOR1: !MONITOR1!
    echo MONITOR2: !MONITOR2!
    echo MONITOR3: !MONITOR3!
    echo DISPLAY_NAME1: !DISPLAY_NAME1!
    echo DISPLAY_NAME2: !DISPLAY_NAME2!
    echo DISPLAY_NAME3: !DISPLAY_NAME3!
)

REM --- ディスプレイ切り替えメニュー ---
:menu
cls
echo ========================================
echo         ディスプレイ切り替え
echo ========================================
echo.
echo 1. 私用 (VG258, LG HD, BenQ EX2510Sを有効化してBenQ EX2510Sをメインにする)
echo 2. 社用 (VG258, LG HDを有効化してVG258をメインにする)
echo 0. 終了
echo.
set /p choice="選択してください (1, 2, 0) > "

if "%choice%" == "1" goto personal
if "%choice%" == "2" goto business
if "%choice%" == "0" goto end

echo 無効な選択です。もう一度入力してください。
pause
goto menu

:personal
echo --- 私用モードを選択しました ---

REM --- ディスプレイ "BenQ EX2510S" を有効化 ---
echo BenQ EX2510S を有効化中...
"C:\Tools\MultiMonitorTool\MultiMonitorTool.exe" /enable "!DISPLAY_NAME2!"
REM --- 3秒待機 (pingで待機) ---
ping -n 3 127.0.0.1 >nul

REM --- ディスプレイ "BenQ EX2510S" をメインモニターに ---
"C:\Tools\MultiMonitorTool\MultiMonitorTool.exe" /SetPrimary "!DISPLAY_NAME2!"

echo ディスプレイ位置を設定中...
"C:\Tools\MultiMonitorTool\MultiMonitorTool.exe" /SetMonitors ^
"Name=!DISPLAY_NAME2! Primary=1 BitsPerPixel=32 Width=1920 Height=1080 DisplayFlags=0 DisplayFrequency=165 DisplayOrientation=0 PositionX=0 PositionY=0"

"C:\Tools\MultiMonitorTool\MultiMonitorTool.exe" /SetMonitors ^
"Name=!DISPLAY_NAME1! Primary=0 BitsPerPixel=32 Width=1920 Height=1080 DisplayFlags=0 DisplayFrequency=60 DisplayOrientation=0 PositionX=-1920 PositionY=0"

"C:\Tools\MultiMonitorTool\MultiMonitorTool.exe" /SetMonitors ^
"Name=!DISPLAY_NAME3! Primary=0 BitsPerPixel=32 Width=1366 Height=768 DisplayFlags=0 DisplayFrequency=60 DisplayOrientation=0 PositionX=1920 PositionY=0"


REM --- ディスプレイ拡張モードを有効化 ---
DisplaySwitch.exe /extend

echo --- VG258, BenQ EX2510S, LG HDを有効化し、BenQ EX2510Sをメインにしました ---
pause
goto end

:business
echo --- 社用モードを選択しました ---


REM --- ディスプレイ "AUS25A4" をメインモニターに ---
"C:\Tools\MultiMonitorTool\MultiMonitorTool.exe" /SetPrimary "!DISPLAY_NAME1!"



REM --- 5秒待機 (pingで待機) ---
ping -n 5 127.0.0.1 >nul

REM --- ディスプレイ "BenQ EX2510S" を無効化 ---
echo BenQ EX2510S を無効化中...
"C:\Tools\MultiMonitorTool\MultiMonitorTool.exe" /disable "!DISPLAY_NAME2!"


REM --- ディスプレイの配置を設定 ---
echo ディスプレイ配置を設定中...
"C:\Tools\MultiMonitorTool\MultiMonitorTool.exe" /SetMonitors ^
"Name=!DISPLAY_NAME1! Primary=0 BitsPerPixel=32 Width=1920 Height=1080 DisplayFlags=0 DisplayFrequency=60 DisplayOrientation=0 PositionX=-1920 PositionY=0"

"C:\Tools\MultiMonitorTool\MultiMonitorTool.exe" /SetMonitors ^
"Name=!DISPLAY_NAME3! Primary=0 BitsPerPixel=32 Width=1366 Height=768 DisplayFlags=0 DisplayFrequency=60 DisplayOrientation=0 PositionX=1920 PositionY=0"

echo --- VG258, LG HDを有効化し、VG258をメインにしました ---
pause
goto end

:end
echo プログラムを終了します。
exit
```

※

```
REM --- モニター設定を表示を確認。 ---
echo MONITOR1: !MONITOR1!
echo MONITOR2: !MONITOR2!
echo MONITOR3: !MONITOR3!
echo DISPLAY_NAME1: !DISPLAY_NAME1!
echo DISPLAY_NAME2: !DISPLAY_NAME2!
echo DISPLAY_NAME3: !DISPLAY_NAME3!
pause
```
はデバック用なので、```set DEBUG=1```を```0```にしてね
***
### 以下詳細

私用中に利用しているモニターの情報はこんな感じ

```
[Monitor0]
Name=\\.\DISPLAY1
MonitorID=MONITOR\AUS25A4\{GUID}\0003
SerialNumber=L8LMQS083776
BitsPerPixel=32
Width=1920
Height=1080
DisplayFlags=0
DisplayFrequency=60
DisplayOrientation=0
PositionX=-1920
PositionY=0
[Monitor1]
Name=\\.\DISPLAY2
MonitorID=MONITOR\GSM5ACD\{GUID}\0002
SerialNumber=
BitsPerPixel=32
Width=1366
Height=768
DisplayFlags=0
DisplayFrequency=60
DisplayOrientation=0
PositionX=1920
PositionY=0
[Monitor2]
Name=\\.\DISPLAY3
MonitorID=MONITOR\BNQ7FA3\{GUID}\0004
SerialNumber=W3R01681019
BitsPerPixel=32
Width=1920
Height=1080
DisplayFlags=0
DisplayFrequency=60
DisplayOrientation=0
PositionX=0
PositionY=0
```

で、最初に、
```MultiMonitorTool.exe /list```
の中身にある
Name=\\.\DISPLAY1
である、```DISPLAYx```が切断、接続したりすると変わると思って、下記変数使ったんだけど、確認中変わる気配がなかったから、やんなくてもいいかも。

```.txt
echo MONITOR1: !MONITOR1!
echo MONITOR2: !MONITOR2!
echo MONITOR3: !MONITOR3!
echo DISPLAY_NAME1: !DISPLAY_NAME1!
echo DISPLAY_NAME2: !DISPLAY_NAME2!
echo DISPLAY_NAME3: !DISPLAY_NAME3!
```

まぁ物理接続を変更すれば変わるので、それ対策ってことでヨシ！ってことに。

DISPLAY1は
```monitor_list.txt
Name=\\.\DISPLAY1
MonitorID=MONITOR\AUS25A4\{GUID}\0003
```
MONITOR1の一つ上の行だからコードすごい取りずらそう

***

#### 次
```
"Name=!DISPLAY_NAME1! Primary=0 BitsPerPixel=32 Width=1920 Height=1080 DisplayFlags=0 DisplayFrequency=60 DisplayOrientation=0 PositionX=-1920 PositionY=0"
```
これがねぇ、どうやってもgptは
```
"MonitorID=!MONITOR1! Primary=0 PositionX=-1920"
```
って答えてきて

どうやらMonitorIDでは実行できないっぽい？のと、

https://qiita.com/TobuHituzi/items/98bfa78876124544f4a9

参考に、全部の設定値入れてやると動くとのことで実行。動いた。

***
#### 次
```Primary=1```
なのに、メインモニターになってくれない(知識不足未解決)
なので、無理やり
```SetPrimary```
使って
```
REM --- ディスプレイ "BenQ EX2510S" をメインモニターに ---
"C:\Tools\MultiMonitorTool\MultiMonitorTool.exe" /SetPrimary "!DISPLAY_NAME2!"
```
でメインモニターに。

なんだけど、社用から私用に移動する際に2:BenQ有効化して、1,2,3位置づけして2メインにすると、
メインに合わせて1,3の位置が無茶苦茶に。
なので、先にメインにすることで適応。(あってるかわかんない

##### 追記

```
FROM GPT
考察
MultiMonitorTool のドキュメントを見る限り、/SetPrimary で動かない場合は、先にすべてのモニターを「有効化」してから「メインモニターを設定」するのが基本のようです。
位置がズレるのは、Windowsが「メインモニターが左にあるべき」という考えでモニターの配置をリセットしてしまうためだと思われます。
```
らしい、確かに、メインにしたら、```PositionX=-1920```が```+3840```になってた。
通りで。
***
待機のところも秒数合わせてないし、要否もわかってない←
ま、動いてるしいいかなって。
***

##### まとめ
動きはしたけど、コード通りに動いているのかは不明
まぁ、動きはしたからいいかなって。