バッチファイルで「既定のブラウザ」をシークレットモード(InPrivateブラウズ、プライベートブラウジング)で起動する

#趣旨
ブラウザにかかわらず**既定のブラウザ**を**シークレットモード**で起動するバッチファイルを作ってみた(Chromeの場合、IE Edgeの場合はInPrivateブラウズ、Firefoxの場合はプライベートブラウジング、以下シークレットモードで統一)

#使い道
このバッチファイルをUSBメモリに入れておけば、ネットカフェや出先のPCでいちいちショートカットキーの入力やメニューの選択をすることなくバッチファイルをダブルクリックするだけでシークレットモードでブラウジングを開始できる。

以下はどういう流れで作ったかという余談なのでバッチだけほしい人は下までスクロールして、どうぞ。

スクリプトとしてはもうちょっとまともな[Powershell版(バッチファイル起動)](https://qiita.com/riafeed/items/51f098b4157441ceda35)もよければどうぞ。

#簡単なようで難しい
こんなの数分であっさりできるだろうと思ってた時期が私にもありました…

既定のブラウザで普通に開くだけなら「 rundll32 url.dll,FileProtocolHandler "url" 」というのがあるのでこれにオプションをつければいいんじゃねと考えた、しかしオプションがブラウザによって全く異なる(IE Edgeは-private Chromeは--incognito Firefoxは -private-window)のでどうにかしてブラウザが何なのかを取得しないといけない…

既定のブラウザが何なのかを知るにはレジストリをreg queryで見るしかないようなので、最初は

`HKEY_CLASSES_ROOT\http\shell\open\command`

の(既定)を見に行くように組んでみたもののそもそもWindows10ではすでに使われてない設定のようで既定ブラウザを切り替えてもIEのまんまでした。
Googleさんにしつこく聞いた結果今は

`HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\Shell\Associations\URLAssociations\http\UserChoice`

のProgIDキーで判別するらしい。

これで既定ブラウザが何なのか分かったのでIFで分岐して対応したオプションをつければちょっと時間かかったけどあっさり完成…と思ってました。

しかしちょっと試した結果

**さっきのコマンドではそもそもオプションをつけられない！**

ということが判明…やりたくなかったけどプログラムのパス取得して直接起動するしかなさげ…

幸い

`HKEY_CLASSES_ROOT\(さっき取得したProgID)\Shell\Open\Command`

でパスが取得できるので取得して起動すればいいのだが、もちろんそのままでは余計な文字列やオプションがふんだんについるのでこれを切り取ったりなんだかんだする必要があってバッチファイルの文字列処理の貧弱さ独特さに悩まされる羽目に

*  %ついた文字列ってどうやって文字列一致させるんだ？→%^1みたいに^を*後ろにつけて*エスケープ
*  "（ダブルクォーテーション）ついた文字列ってどうやって文字列一致させるんだ？→%%~iみたいに変数のほうにチルダ付ける
*  空白で切るとパスが途中で切れるぞ→いくつか取得して代入でくっつけるしかなさげ
*  for内の変数おかしくね？→遅延展開しないといけないっぽい
*  正規表現使えるの？→findstrコマンドしかなさげ
*  findstrコマンドで変数の検索ってどうやるんだ？→echoからパイプするしかなさげ

と試行錯誤を繰り返した結果なんとか3つのブラウザでは起動にまでこぎつけた。
しかし、Edgeだけはどうしてもうまくいかない。

#Edge特殊すぎ

Edgeはほかのブラウザとは違い、実行ファイルを直接指定しても起動しないらしい。現にさっきのレジストリを参照するとEdgeが既定の場合は

`C:\Windows\system32\LaunchWinApp.exe`

となってるんでまぁこれを使えばいいのかなと考えた。しかし…

**さっきのコマンドではそもそもオプションをつけられない！**(2回目)

ということが判明、えぇ…

調べた結果

`%windir%\system32\cmd.exe /c start shell:AppsFolder\Microsoft.MicrosoftEdge_8wekyb3d8bbwe!MicrosoftEdge`

とすればオプション付きで起動できるらしい。

Edgeのときはこのコマンドにして起動するようにすればいいな。

コマンドラインではうまくいくのにバッチに記載するとうまくいかない、
どうやら遅延展開で!が使えなくなっていたためうまくいかなかったらしい…~~わかるかそんなん~~

#完成品

とりあえずどうぞ、改善の余地ありすぎ…

※20/2/21　
新しいChromiumベースのEdgeに対応してみた
Edge(EdgeHTMLベース)がバージョンアップでいつの間にか[Powershell経由でしかオプションを受け付けなくなったよう](http://etsux.hatenablog.com/entry/2019/08/04/102641)なので修正

```ptivate.bat
@ECHO OFF

SETLOCAL ENABLEDELAYEDEXPANSION

REM 設定
REM 最初に開くページを指定
SET OPENFILE=

SET /A ISEDGE=0
SET EXPR="^[-%%].*"
SET /A PT=0

FOR /F "USEBACKQ TOKENS=3 DELIMS= " %%i IN (`REG QUERY HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\Shell\Associations\URLAssociations\http\UserChoice /V ProgId`) DO (
  SET PROGID=%%i
)

FOR /F "USEBACKQ TOKENS=3-8 DELIMS= " %%i IN (`REG QUERY HKEY_CLASSES_ROOT\!PROGID!\Shell\Open\Command /VE`) DO (

  ECHO %%~j | FINDSTR /R %EXPR% >NUL
  IF NOT ERRORLEVEL 1 (
    SET BROWSER=%%i
    GOTO SETOPTION
  ) 

  ECHO %%~k | FINDSTR /R %EXPR% >NUL
  IF NOT ERRORLEVEL 1 (
    SET BROWSER=%%i %%j
    GOTO SETOPTION
  ) 

  ECHO %%~l | FINDSTR /R %EXPR% >NUL
  IF NOT ERRORLEVEL 1 (
    SET BROWSER=%%i %%j %%k
    GOTO SETOPTION
  ) 

  ECHO %%~m | FINDSTR /R %EXPR% >NUL
  IF NOT ERRORLEVEL 1 (
    SET BROWSER=%%i %%j %%k %%l
    GOTO SETOPTION
  ) 

  ECHO %%~n | FINDSTR /R %EXPR% >NUL
  IF NOT ERRORLEVEL 1 (
    SET BROWSER=%%i %%j %%k %%l %%m
    GOTO SETOPTION
  ) 

  SET BROWSER=%%i %%j %%k %%l %%m %%n
)

:SETOPTION

ECHO !BROWSER! | FINDSTR /I "LaunchWinApp" >NUL
IF %ERRORLEVEL% == 0 (
  REM EDGE(EdgeHTMLベース)です
  SET /A ISEDGE=1
  GOTO EXECUTE
)

ECHO !BROWSER! | FINDSTR /I "msedge" >NUL
IF %ERRORLEVEL% == 0 (
  REM EDGE(Chromiumベース)です
  SET OPT=--inprivate
  GOTO EXECUTE
)

ECHO !BROWSER! | FINDSTR /I "iexplore" >NUL
IF %ERRORLEVEL% == 0 (
  REM IEです
  SET OPT=-private
  GOTO EXECUTE
)

ECHO !BROWSER! | FINDSTR /I "chrome" >NUL
IF %ERRORLEVEL% == 0 (
  REM chromeです
  SET OPT=--incognito
  GOTO EXECUTE
)

ECHO !BROWSER! | FINDSTR /I "firefox" >NUL
IF %ERRORLEVEL% == 0 (
  REM firefoxです
  SET OPT=-private-window
  GOTO EXECUTE
)

:EXECUTE
IF %ISEDGE%==0 ( 
  START "" !BROWSER! !OPT! %OPENFILE%
) ELSE ( 
  ENDLOCAL
  powershell.exe start shell:AppsFolder\Microsoft.MicrosoftEdge_8wekyb3d8bbwe!MicrosoftEdge '-private %OPENFILE%'
) 
```

#改善案(機能的な意味で)


* 環境変数とは別にパラメータで最初に開くHTMLファイルやURLを指定できるようにしたい
* 既定のブラウザではなくパラメータでブラウザを指定できるようにしたい