chrome.exeの引数を指定して、WEBアプリとして開く（タブを作れない状態にする）

# はじめに
　 こんにちは、またバイト先でお願いされたシステムを作るにあたって、調べたことをまとめたいと思います。多分、自分以外にあまり需要がない記事だと思いますが、勉強だと思って記事にまとめます。
　いつも通り、前置きが長い記事になったので、方法だけ知りたい人は[ここ（実際にやってみる）](https://qiita.com/mimuro_syunya/items/e30fb254e050b5fa47d9#%E5%AE%9F%E9%9A%9B%E3%81%AB%E3%82%84%E3%81%A3%E3%81%A6%E3%81%BF%E3%82%8B)から読んでください。

# この記事から得られること
　このを読むことで、以下のことが得られます。

・chrome.exeの引数を指定することで、"WEBアプリとして開く"状態で起動できる（タブを開けない状態で起動できる）。

 主にseleniumを使って、ユーザーのWEBアプリを監視する状況を想定しています。のちに述べますが、先日書いた[PythonのSeleniumを使って、起動済みのブラウザを操作する。](https://qiita.com/mimuro_syunya/items/2464cd2404b67ea5da56)という記事では、タブを作られる状況は好ましくないのです。

# 誰向けの記事？
　この記事は、

・コマンドプロンプトやバッチファイルからchrome.exeを実行する際、タブを作れないようにしたい
・OSはWindowsで開発します

っていう人向けです。

# なぜこれが必要になったのか？
　結論から言うと、「seleniumでWEBを監視する際、タブを新たに作られると厄介だから」です。
　今回バイト先で作るシステムは、WEB上で操作するアプリケーションを監視するシステムで、業務中に新たにタブを開くことは想定していません。しかし、誤ってタブを開いてしまう可能性は重々あります。
　また先日、[PythonのSeleniumを使って、起動済みのブラウザを操作する。](https://qiita.com/mimuro_syunya/items/2464cd2404b67ea5da56)という記事を書きましたが、これには厄介な点があります。それは、”複数タブへの対応が面倒”という事です。seleniumでWEBを監視する場合、初期では最初に開いたタブに対応しています。それは複数タブを開いた場合も同じです。

　ここで厄介なことが起きそうですね。例えば以下の状況。

カウンターの職員：「あ、同じページの新しいタブ作っちゃった。」
監視システム　　：「新しいタブ作られたけど、古い方を監視してればいいんだな」
カウンターの職員：「２つあるとややこしいから、古いの消しちゃえ。」
監視システム　　：「え、監視対象のタブなくなったんやけど。。。」→エラー

こうなる訳です。これを回避する方法としては、２つのパターンがあります。

パターン１．一定時間ごとにウィンドウを切り替え、すべてのウィンドウを監視する
パターン２．新しくタブを作れない仕様にする

パターン１については、Seleniumの`driver.switch_to.window`([Seleniumで操作するウィンドウを切り替える２つの方法を紹介](https://tanuhack.com/selenium-change-window/#driverswitch_towindow))とかを使えば出来ますが、とても煩雑になります。なぜなら、python側でウィンドウを切り替えると、ユーザーが触っているChromeのタブも切り替わるからです。また、その問題を無視したとしても、すべてのウィンドウを監視するのはシステムが複雑になりますね。

という事で、パターン２の「新しくタブを作れない仕様」にする為、"WEBアプリ"としてchrome.exeを開けばいいんじゃね？という事になりました。

# タブを作れない状態である"WEBアプリとして開く"というショートカット
　普通、chromeでサイトにアクセスすると、こんな感じになりますよね。もちろんタブの追加ボタンがあります。(面倒なんで目隠ししませんでした。阿部寛さんごめんなさい。)
![2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554112/f96c1d09-169b-1476-2c09-02cace0187d2.png)
　しかし、chromeでは、ショートカットを作るとき”WEBアプリとして開く”ってのがあります。実は、それで開くとこんな感じになるんです。このモードだと、新しくタブを作る機能が削ぎ落されています。これにより、アプリとしてChromeを起動しているのです。
![7.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554112/a7f7771c-e0bf-bdd8-7def-2b1123339e43.png)
　そして、これはショートカットとして作られます。つまり、そのコマンドがショートカットのプロパティから見れる！という事ですね。今回はこの発想で行きます。

# 実際にやってみる
　手順としては３つあります。「①Chromeのポート番号を固定し、起動する」と「②　①で起動しているchromeからショートカットを作る」「③必要な引数を取り出し、コマンドを書き換える」です。①に関してはできる人も多いと思うので、読み飛ばしでも分かると思います。
　ちなみに①は以前に書いた記事からコピペしました。すんません。

## ①Chromeのポート番号を固定し、起動する
### chrome.exeのパス探し
　実はChromeでは、EXEファイル実行時にパラメータを渡してやることによって、クライアント側であるChromeのポート番号を固定することが出来ます。その為にもまず、Chrome.exeのPathを知っておくと便利でしょう。という事で、Windowsのアプリ一覧から、下の3枚の画像みたいに、Chromeのパスを探していきましょう。

１．アプリ一覧からChromeを右クリックし、その他から「ファイルの場所を開く」をクリック
![スクリーンショット (339).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554112/ac1a49ba-31e8-a9a2-3b98-2f9d7ceafa15.png)
２．ショートカットに飛ばされるので、それを右クリックし、「ファイルの場所を開く」をクリック
![スクリーンショット (340).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554112/824b5113-31e7-97d2-e4d8-3f25a856300d.png)
３．chrome.exeがある場所が示されるので、ここまでのパスをメモする。
![スクリーンショット (341).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554112/4c1441da-0853-c2bb-5a65-76bb0753a3c4.png)

私の場合、パスは`C:\Program Files\Google\Chrome\Application\chrome.exe`でした。

### ポートを固定する引数を指定しながらchrome.exeを実行する
　Chromeは、コマンドプロンプトから実行する場合、引数を指定できます。そして今回、以下の2つの引数を指定します。

`-remote-debugging-port=9222`
`--user-data-dir="適当なパス（chromeのデータがいっぱいできても良い場所）"`

上のremoteなんちゃらは、chromeのポート番号（クライアントとサーバーでいうと、クライアント）を9222番に固定しています。そして、userなんちゃらは、chromeを動作する上での、諸ファイルを保存しておく場所です。適当でいいですが、結構沢山ファイルができるので注意です。
　そして、コマンドプロンプト上で、以下のコマンドを実行する事で、ポート番号を固定しながらchromeを開くことが出来ます。

```ruby:portを固定しchromeを開く(cmd上)
"C:\Program Files\Google\Chrome\Application\chrome.exe" -remote-debugging-port=9222 --user-data-dir="適当なパス（chromeのデータがいっぱいできても良い場所）"
```

### 実行コマンドをbatファイルにする
　このままでは、chromeを実行するたびに、コマンドプロンプトでながぁ～いコマンドを打ち込まなきゃいけません。めんどうですね。なので、上記の内容をバッチファイルにしておきましょう。メモ帳上で以下の内容を書き込んで、拡張子を".bat"で保存すればokです。

```ruby:openChrome.bat
"C:\Program Files\Google\Chrome\Application\chrome.exe" -remote-debugging-port=9222 --user-data-dir="適当なパス（chromeのデータがいっぱいできても良い場所）"
```

## ②　①で起動しているchromeからショートカットを作る
　ここは簡単ですね。題名通りです。まず、さっき作ったバッチファイルを実行し、阿部寛の公式サイト（http\://abehiroshi.la.coocan.jp）を開きましょう。（ポート番号を指定して開かないと意味ないです。コマンドから実行し、`-remote-debugging-port`と`--user-data-dir`が指定されている状況で開きましょう）

１．阿部寛のサイトに行く
![2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554112/60a121f0-d2ce-3615-9092-aca757f1d9fd.png)
２．設定のその他のツールから、ショートカットを作成をクリック
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554112/8594420c-84a8-8d28-4b96-f4fc07210faa.png)
３．ショートカット作成時に”ウィンドウとして開く”にチェックを入れ、作成
![4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554112/d618c822-b3d1-b12e-a020-7f3180976308.png)
４．デスクトップ上にショートカットが作成される。
![5.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554112/37870142-287c-46a5-d507-8a6c4e7e730c.png)

## ③必要な引数を取り出し、コマンドを書き換える
### ショートカットから引数を取り出す
　ここでは、先ほど作成したショートカットから、WEBアプリとして開くための引数を取り出します。先ほどのショートカットのプロパティを見てみましょう。リンク先という欄にコマンドが書いてあります。
![6.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554112/72ed7483-d5f8-009c-480c-e9cf21155e16.png)
このコマンドを見ると、以下の構成になっています。ここで注目してほしいのは、3つ目と4つ目の引数です。`--profile-directory=Default`と`--app-id=(なんかすごい文字列)`、これが①で指定しなかった引数であり、"WEBアプリとして開く"ための引数となります。ちなみに、`--user-data-dir`は①と同じになっているはずです（同じじゃないといけません）。
　また、これは予想なのですが`--app-id`は②の手順が終わった時点で作られていると思います。つまり、②の手順が終了した時点で`--user-data-dir`へ、阿部寛のサイトが"WEBアプリ"として登録され、IDが発行された。と思います。

```ruby:ショートカットのコマンド
"C:hoge\chrome_proxy.exe"  --user-data-dir="C:hogehoge" --profile-directory=Default --app-id=(なんかすごい文字列)
```
という事で、ショートカットのプロパティから以下の要素をメモしましょう。

・`--profile-directory=Default`
・`--app-id=(なんかすごい文字列)`

### コマンドを書き換える
　必要な引数が分かったら、①で作ったバッチファイルの後ろに、コマンドを追加しましょう。こんな感じに。

```ruby:修正後のopenChrome.bat
"C:\Program Files\Google\Chrome\Application\chrome.exe" -remote-debugging-port=9222 --user-data-dir="適当なパス（chromeのデータがいっぱいできても良い場所）" --profile-directory=Default --app-id=(なんかすごい文字列)
```

さあ、できました！最後に、修正後のバッチファイルをクリックしてみると、タブなし阿部寛がひらけますね！やったね！終わりです。
![7.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554112/a7f7771c-e0bf-bdd8-7def-2b1123339e43.png)

# おわりに
　いつも通り、説明ばっかりになっちゃって申し訳ありません。それに、こんなマニアックなシチュの解決記事を出したところで、あまり世間に役立たないかもしれません。でも書きたかったのです！
　また、ご指摘などございましたら、ご教授いただけると幸いです。という訳で、ここまで読んでくださった方、ありがとうございますm(_ _)m。
　それじゃ！