最初はexec(3)でした。実行可能ファイルへのパスと引数へのポインタの可変長リストを受け入れます。正常なオペレーティングシステムでは、開始されるプロセスは引数リストにポイントを受け取り、各単語にはポインタと個々の文字列が含まれます。 saneシェルはコマンドラインを解析し、exec(3)で必要な引数リストに値を設定します。
exec ("some.executable.file", "arg1" , "arg2" , "arg3" , ...) ;
とどのようなプロセスのエントリポイントに渡されます:
int型の主(のchar *の引数の[
あなたは、exec(3)が受け付ける引数リストとの間に直接的な相関関係を見ることができます]){...}
argv[0]
が実行可能ファイル名であり、argv[1]
— argv[n-2]
、個々の引数であり、argv[n-1]
を示すNULLポインタであります引数リストの最後。
概念的に単純で実装が簡単です。
CP/Mはそうしていません(メモリが限られていると思います)。これは、起動されたプロセスにシェルからの生のコマンドラインのアドレスを渡し、そのプロセスの解析を残しました。
DOSは1982年にCP/Mのクローンとして続いて、開始されたプロセスに未処理のコマンドラインのアドレスも渡しました。
Windowsは当初からそのモデルから逸脱していません。 Win32のCreateProcess()
機能
BOOL WINAPI CreateProcess(
__in_opt LPCTSTR lpApplicationName,
__inout_opt LPTSTR lpCommandLine,
...
);
はまだプログラムに渡される生のコマンドラインを渡して、同じことを行います。もちろん、Cランタイムライブラリは、あなたのためにコマンドラインを解析します。多かれ少なかれ。
CLR/.Netの世界では、このすべての履歴が原因で、CLRがWin32 APIに依存するように設計されているため、開始するプロセスに完全なコマンドラインを渡しています。なぜ彼らはあなたにparams string[]
を渡させず、CLRにコマンドラインをビルドさせるのは、マイクロソフトの開発者が胸に近づけたものです。
起動したプログラムで必要なコマンドラインを構築するのは簡単です。それぞれの引数を、引数を区切るSP文字を持つ単一の文字列に結合するだけです。簡単!
...あなたの引数の1つに空白または二重引用符("
)が含まれるまで。
次に、引数の1つまたはすべてを引用する必要があります。簡単なはずですが、奇妙な見積もり規則のために、あなたを上に向けることができる多くのエッジ条件があります。
Windowsのコマンドラインは、空白で区切られた単語に分割され、二重引用符("
)で任意に引用されます。 Windowsにはパス区切りが間違っている(\
ではなく/
)ので、引用規則は... byzantineです。 Windows CRTのソースコード(ファイルは{Visual StudioInstallLocation} \ VC \ crt \ src \ stdargv.cのようなものです)を掘り下げると、コマンドラインの解析コードが見つかります。
サンプルコードですが、間違いありません。しかし、実際には使用しないでください。Directory.GetFiles()メソッドは同じことを*ロット*少ないオーバーヘッドで行います。 –