ディレクトリの右クリックメニューから、見た目が良いコマンドプロンプトを開けるようにする

エクスプローラで今見ているディレクトリを作業ディレクトリとするコマンドプロンプトを開きたい！
Power Shellを開くメニューはあるけど、宗教上の理由などによりNG！
普通にコマンドプロンプトを開いて`cd`するのはめんどくさい！
あと`/d`オプションを忘れて作業ディレクトリが変わらないミスを起こす！

…そんなお悩みを解決するため、エクスプローラでディレクトリを右クリックしたときのメニューに
「コマンド プロンプトをここで開く」を追加します。

# 免責

ここで紹介する手順では、レジストリエディタを用います。
レジストリエディタを用いた作業では、
間違えるとOSが起動しなくなるなどの重大な障害が起こる可能性があると言われています。
作業を行う場合は、十分注意し、自己責任でお願いします。

# 普通のコマンドプロンプトを開けるようにする

レジストリエディタで、
現在のユーザーのみで使えるようにするには`HKEY_CURRENT_USER\Software\Classes\Directory`キーを、
全ユーザーで使えるようにするには`HKEY_CLASSES_ROOT\Directory`キーを開きます。
以下、このキーを`...\Directory`と呼びます。

追加するメニューのキーの名前を適当に、他のキーと衝突しないように決めます。
ここでは`open_cmd`とします。

`...\Directory\shell\open_cmd`キーを作成し、
そこの値`(既定)`のデータとして追加するメニューに表示する文字列を設定します。(`open_cmd`は決めた名前、以下同じ)
例えば「コマンド プロンプトを開く」とします。
また、ここで`@shell32.dll,-8506`に設定すると、
システムで適当に決められた文字列(例えば「コマンド ウィンドウをここで開く(W)」)が表示されるようになります。

`...\Directory\shell\open_cmd\command`キーを作成し、
そこの値`(既定)`のデータとして`cmd.exe /s /k pushd "%V"`を設定します。
設定の意味は、

* `cmd.exe` : コマンド プロンプトを開く
* `/s` : コマンド中の引用符を解釈せず、コマンドの一部として扱う
* `/k` : 以下のコマンドを実行し、その後終了せずに操作を受け付ける
* `pushd` : 指定のディレクトリに移動する
* `"%V"` : 右クリックされたディレクトリ

となり、合わせて「コマンド プロンプトを開いて右クリックされたディレクトリに移動する」という意味になります。

`...\Directory\Background\shell\open_cmd`キーを作成し、
そこの値`(既定)`のデータとして同様に追加するメニューに表示する文字列を設定します。

`...\Directory\Background\shell\open_cmd\command`キーを作成し、
そこの値`(既定)`のデータとして同様に`cmd.exe /s /k pushd "%V"`を設定します。

`...\Directory\shell\open_cmd`の追加は
「ファイル/フォルダ一覧中のフォルダを右クリックした時のメニュー」への追加となり、
`...\Directory\Background\shell\open_cmd`の追加は
「ファイル/フォルダ一覧部の何もない場所を右クリックした時のメニュー」への追加となります。

このメニューを選択すると、以下のようなコマンドプロンプトが開きます。
![普通のコマンドプロンプト](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/aa833a09-4cbf-ab43-bb69-bd80ec340b4d.png)

この`cmd.exe /s /k pushd "%V"`を用いた方法は多くのサイトで紹介されていますが、
この方法で出せるようになるコマンドプロンプトは、
ウィンドウタイトルがパスになっており、普通にコマンドプロンプトを開いた時に出るヘッダも出ていません。
以下の方法を用いると、これらの点を解消したコマンドプロンプトを出せるようになります。

# 見た目が良いコマンドプロンプトを開けるようにする

コマンドプロンプトの設定は、ショートカットに保存されるようです。
また、コマンドプロンプトの起動に用いたショートカットの名前が、ウィンドウタイトルになるようです。
そこで、右クリックからショートカットを用いてコマンドプロンプトを開けるようにします。

まず、スタートメニューから適当なディレクトリにコマンドプロンプトのショートカットをコピーします。
スタートメニューのコマンドプロンプトのショートカットは、例えば
`C:\Users\(ユーザー名)\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\System Tools`
の中にあるようです。
Windows 10の場合、スタートメニューの中の「Windows システム ツール」フォルダの中にある
「コマンド プロンプト」を右クリックし、「その他」→「ファイルの場所を開く」で開くことができます。

コピーしたショートカットを、ウィンドウタイトルにしたい文字列(例えば「コマンド プロンプト」にリネームします。

コピーしたショートカットのプロパティを開き、「作業フォルダー」を空に設定します。
このことにより、ショートカットを開くプログラムの作業ディレクトリを作業ディレクトリとした
コマンドプロンプトを開くことができるようになります。
![ショートカットのプロパティ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/61d768a7-4b29-2cb7-3423-f22af673d09f.png)

次に、このショートカットを開くプログラムを作ります。
今回は、Windows標準で実行できるようにJScriptを用います。

以下のようなプログラムを書き、拡張子`.js`、文字コードShift_JISで保存します。

```js
var args = WScript.Arguments;

var app = new ActiveXObject("Shell.Application");
var cmd = "C:\\MyCreatedApps\\opencmd\\コマンド プロンプト.lnk";
var dir = args.length >= 1 ? args(0) : "";
app.ShellExecute(cmd, "", dir, "open", 1);
```

変数`cmd`には、実際にコピーしたショートカットのパスを入れるようにしてください。
例として`open_cmd`ディレクトリを用いていますが、これはレジストリのキーの名前とは関係ありません。
これは、[Shell.ShellExecuteメソッド](https://docs.microsoft.com/en-us/windows/win32/shell/shell-shellexecute)を用い、
引数で指定したディレクトリを作業ディレクトリとして指定のショートカットを開くプログラムです。

ショートカットとそれを開くプログラムを用意したら、
「普通のコマンドプロンプトを開けるようにする」と同様にレジストリの設定を行います。
ただし、`cmd.exe /s /k pushd "%V"`のかわりに、
いずれも`C:\Windows\System32\WScript.exe (ショートカットを開くプログラムのパス) "%V"`を設定します。
例えばこのプログラムを`C:\open_cmd\open_cmd.js`に保存したとすると、
設定するデータは`C:\Windows\System32\WScript.exe "C:\open_cmd\open_cmd.js" "%V"`となります。

このメニューを選択すると、以下のようなコマンドプロンプトが開きます。
![見た目が良いコマンドプロンプト](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/053808df-820a-8adc-0602-9ec492adb5f6.png)
ショートカットのファイル名がウィンドウタイトルに反映され、ヘッダも出ています。

# レジストリの設定まとめ

* リストの中のディレクトリ
  * `...\Directory\shell\(名前)`キーの(既定)：メニューに表示する文字列
  * `...\Directory\shell\(名前)\command`キーの(既定)：そのメニューで実行するコマンド
* 今見ているディレクトリ(背景を右クリック)
  * `...\Directory\Background\shell\(名前)`キーの(既定)：メニューに表示する文字列
  * `...\Directory\Background\shell\(名前)\command`キーの(既定)：そのメニューで実行するコマンド

ただし、`...\Directory`とは
現在のユーザー：`HKEY_CURRENT_USER\Software\Classes\Directory`
全ユーザー：`HKEY_CLASSES_ROOT\Directory`

コマンド中に`%V`を書くと、対象のディレクトリのパスに展開される