2016年12月29日

環境変数COMSPECとコマンドラインシェルとPowerShell

12月12日に、コマンドプロンプトが無くなるという話題が出てきて一時騒然という話題を出しました。このときは、コマンドプロンプトが無くなるわけではなく、デフォルトのコマンドラインシェルがPowerShellに置き換わるらしいという話で落ち着いたことを書きました。

おそらく、スタートメニューからのリンクが「コマンド プロンプト(CMD.EXE)」から「パワーシェル(PowerShell.exe)」に変わるとか、環境変数COMSPECがPowerShell.exeへのパスに変わるのか…といった予想を書きました。

最近のInsider Previewを試した人の話によると、スタートボタンを右クリック or Windows+Xキーを押したときに表示される「コマンドプロンプト」へのリンクは「PowerShell」に変更になったが、環境変数COMSPECは依然としてCMD.EXEのままであったとのことです。

なお、これを変更するための設定は「タスクバー」の設定内に、現バージョンでもすでに準備されており、それのデフォルトが「PowerShell」側に置き換わっただけというだけのこと.
tskbar_cmd.png


というわけで、CMD.EXEを利用するプログラムも書いたことがあるプログラマとしては一安心だったのですが、これを調べる過程で、ちょっと怖いテクニックを紹介しているページがあって慌てています。

どこに恐怖したかというと、環境変数COMSPECをPowerShellに変更するというテクニックを紹介しているところですね。
これをやっている人が世の中にどれだけいるか、わからないけど、少なくともこれを実践している人がいると、当サイトで作っているソフトウェアのうち、環境変数COMSPEC経由でコマンドプロンプトを呼び、内部コマンドを使用しているものは、うまく動作しなくなるということ。

例えば、「改行コード変換Lite」は、各機能がGUIプログラムとは独立に子プログラムとして作られており、GUIプログラムはCMD.EXE用のコマンドラインを生成して子プログラムを実行する仕組みになっています。

このとき、一時停止には内部コマンドPAUSEを使っているし、複数ファイル処理するときには内部コマンドFORを使っています。
PowerShellにPAUSEはありませんし、FORの書式は全く違うものになっていますから、このままでは「改行コード変換Lite」は動作しなくなってしまいます。

環境変数COMSPECをPowerShellに変更するテクニックを実践している人は「改行コード変換Lite」が使えないことになってしまいます。
まぁ、そんな特異なことをしている人は自業自得だ・・・と言ってしまえばソレまでなのですが、うまく動作しない原因が環境変数COMSPECをPowerShellに変更するテクニックを実践しているためだと気づける人の方が希だと思いますので、それに気づかせるための手立てを準備するか、あるいは解決策を準備する必要があるかもしれません。

(作者にクレームが来れば気づかせて上げることもできるかもしれませんが、昨今では作者にクレームを入れるのではなく、2chやTwitter上で騒ぎ立てるだけ騒ぎ立ててオシマイで解決せず、作者だけが悪者になっているケースもあったりしますから、慎重に考えなければなりません)

例えば、COMSPEC内にCOMMAND.COMでもなく、CMD.EXEでもない文字列が入っていたら・・・、あるいはPowerShell.exeのような文字列が入っていたら起動時に警告メッセージを出力するとか。

あるいは、デフォルトではコマンドラインシェルを環境変数COMSPEC依存とするが、設定変更により自由にコマンドラインシェルを選べるようにする(C:\Windows\System32\Cmd.exeを直指定できるようにする)とか。

一般的に、こういったプログラムを書くときは、環境変数経由でファイル名を指定してやるのがキレイなことで、逆に直指定は汚いことであるというのが共通理解かと思うのですが、環境変数COMSPECに依存するとこんな落とし穴にハマってしまうとは、プログラムを書いていたときには全く気づきませんでした…。


続きを読む
posted by ayacy at 09:32 | Comment(0) | TrackBack(0) | PC