
に触発された今日のDailyWTF記事。
C:\Program.exe
作者は、たとえばへのショートカットをクリックするとファイルが実行されると主張していますC:\Program Files\Doom 2\doom2.exe -nomusic
。
おそらく、Windows は最初にC:\Program
引数を使用して呼び出すことを試みますFiles\Doom 2/doom2.exe -nomusic
。
がない場合C:\Program.exe
、C:\Program Files\Doom
引数 を試します2/doom2.exe -nomusic
。
そして、 がない場合にはC:\Program Files\Doom.exe\
、最終的に試行しC:\Program Files\Doom 2\doom2.exe -nomusic
て成功します。
これはまったくナンセンスに思えます。こんなふうに機能するなんて信じられません。あるコメント者はそれをうまく表現している:
Windows のリリースされたバージョンで、OP が説明したような試行錯誤のアプローチが採用されたとは信じがたい。
リリースされたバージョンの Windows にはデフォルトで愚かな動作が備わっていたと確信しています。私はそれを何度も直接経験しました。
私が信じられないのは、Windowsのリリース版にこれ記事に書かれているように、これは脳死状態の動作です。これは、XP より前のバージョンの Windows で発生したはずなので、少なくとも 10 年後、Daily WTF のランダムな投稿によって発見されるまで気付かれないほどのセキュリティ上の欠陥です。
わかりやすくするために編集:私がこれを自分でテストした方法は次のとおりです。
- notepad.exe を C:\program.exe にコピーします。
- C:\program files\Internet explorer\iexplore.exe を実行します。
- メモ帳が開きます。C:\program という名前が見つかるので、これは予想通りです。
- progam.exe を C:\program files\Internet.exe に移動します。
- C:\program files\Internet explorer\iexplore.exe を実行します。
記事の著者によると(そしてマイクロソフトのこの記事) の場合、メモ帳は開くはずです。しかし、開かず、コマンドは次のメッセージで失敗します。
C:\program is not recognized as an internal or external command, operable program or batch file.
繰り返しますが、私は C:\program が呼び出されるという記事の主張について議論しているわけではありません。Windows が一致するまですべてのディレクトリを再帰的に試行するということについて議論しているのです。
それで、Windows のどのバージョンもこのように動作したことがあったのでしょうか?
答え1
長いファイル名が追加されて以来、Windows 95 から Windows 7 までのすべてのバージョンの Windows はこのように動作します。
この行動は文書化された:
のアプリケーション名パラメータはヌルその場合、モジュール名は、 コマンドライン文字列。スペースを含む長いファイル名を使用する場合は、引用符で囲んだ文字列を使用してファイル名の終了位置と引数の開始位置を示します。そうしないと、ファイル名があいまいになります。たとえば、文字列「c:\program files\sub dir\program name」を考えてみましょう。この文字列は、さまざまな方法で解釈できます。システムでは、次の順序で可能性を解釈しようとします。
c:\program.exe files\sub dir\program name c:\program files\sub.exe dir\program name c:\program files\sub dir\program.exe name c:\program files\sub dir\program name.exe
なぜこのように尋ねるのかというと、ファイル名のスペースを正しく処理できないプログラムを壊さない。
編集
「実行」コマンドはこのように動作しないようです。まさにこのケースを処理するために、何らかの追加ロジックを追加する必要があります。ただし、他の場所から実行しようとすると、CreateProcess
ほとんどのアプリケーションがコマンドを実行するために使用する関数を直接使用することも含まれます。
この動作を実際に見てみましょう:
- 管理者コマンドプロンプトを開く
- 走る:
copy c:\Windows\System32\notepad.exe c:\program.exe
- 走る:
c:\Program Files\Internet Explorer\iexplore.exe
- メモ帳が開き、見つからないと表示されます
Files\Internet Explorer\iexplore.exe
c:\Program Files\Internet Explorer\iexplore.exe
実行オプションに入力すると、IE が正しく開きます。
編集2あなたの例の場合C:\program files\internet.exe
、これはコマンド ライン インタープリターが邪魔をしているのだと思います。インタープリターは、コマンド ラインを処理して、スペースで区切られたパラメーターにトークン化しようとします。つまり、C:\program
最初のトークンを取得し、それをプログラム名として解釈し、残りをパラメーターとして解釈します。
テスト用に、CreateProcess
直接 を呼び出す小さなアプリケーションを作成しましたが、ドキュメントに記載されているとおりに動作します。C:\program files\internet.exe
例では が起動しますC:\program files\internet.exe
。したがって、動作はコマンドの実行方法によって決まるようです。つまり、 に渡す前に何らかの処理によってコマンド ラインが処理されている可能性がありますCreateProcess
。
サンプルプログラム:
#include <Windows.h>
void main()
{
STARTUPINFO si = {0};
si.cb= sizeof(si);
PROCESS_INFORMATION pi = {0};
CreateProcess(NULL, "c:\\program files\\internet explorer\\iexplore.exe",
NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
}
答え2
前の回答に何か付け加えたいことがあります。
この動作を、努力、不適切なプログラミング (RTFM ではない)、またはこの特定のウイルス対策プログラムによって引き起こされる検証不可能な最悪の状況によって強制することは可能ですが、記事で説明されている動作を引き起こすものは何もありませんでした。正しく作成されたショートカット (たとえば、引用符付きの "C:\Program Files\Microsoft\Office\Word.exe" をターゲットとするショートカット) が C:\Program.exe を実行することは絶対にありません。Firefox でも同様です。実際、適切にエスケープされないショートカットを作成することは基本的に不可能です。なぜなら、それはインテリジェントに行われるからです。
デスクトップに Firefox を指すショートカットを作成すると、適切にエスケープされます。右クリック -> プロパティで引用符を削除しようとすると、C:\Program.exe が存在する場合でも、適用をクリックすると自動的に引用符が挿入されます。これを解析すると、フォルダーを優先するか、最後の '\' の前のすべてをパスの一部として扱うかのどちらかになると思います。Program と Files の間に 2 つのスペースを挿入した場合にのみ、引数付きの C:\Program.exe を指すものとして解析されます。ショートカットをテキスト エディターで編集できる場合 (プレーン テキストではない)、機能する可能性があります。
ショートカットと同様に、実行ダイアログも文字列を正しく解析します。比較的低レベルのコマンド コンソールでのみ、誤って C:\Program.exe を呼び出しますが、他のさまざまな可能性は試しません。つまり、誤って "C:\Program.exe" を呼び出そうとしますが、"C:\Program Files\Internet.exe" やその他の可能性が存在する場合でも、それらの呼び出しは試みません。C:\Program.exe が見つからないというエラーが返されます。
さらに、C:\ フォルダに Program.exe がある場合、起動時に警告が表示され、名前を変更するかどうか尋ねられます。これは、XP、Vista、Windows 7 で確認されており、Windows 8 でも確認できるようになりました (http://goo.gl/eeNCp)。多分これは Windows 9x では可能でしたが、疑問です。
要するに、これは明白であり、Windows プログラマーがこの間違いを犯すことはありません。