@prefix schema: <https://schema.org/> .
@prefix skos: <http://www.w3.org/2004/02/skos/core#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix ks: <https://comcomponent.com/vocab/> .

<https://comcomponent.com/blog/windows-command-line-argument-rules/#article>
    schema:about <https://comcomponent.com/knowledge/windows-command-line-string/>, <https://comcomponent.com/knowledge/command-line-backslash-quote-rule/>, <https://comcomponent.com/knowledge/argument-quoting-function/>, <https://comcomponent.com/knowledge/processstartinfo-argumentlist/> ;
    schema:mentions <https://comcomponent.com/knowledge/createprocess/>, <https://comcomponent.com/knowledge/lpapplicationname/>, <https://comcomponent.com/knowledge/getcommandlinew/>, <https://comcomponent.com/knowledge/commandlinetoargvw/>, <https://comcomponent.com/knowledge/msvc-crt-argument-parsing/>, <https://comcomponent.com/knowledge/dotnet-command-line-segmentation/>, <https://comcomponent.com/knowledge/setargv-wildcard-expansion/>, <https://comcomponent.com/knowledge/argv0-program-name-rule/>, <https://comcomponent.com/knowledge/trailing-backslash-quote-pitfall/>, <https://comcomponent.com/knowledge/doubled-quote-form/>, <https://comcomponent.com/knowledge/processstartinfo-arguments-string/>, <https://comcomponent.com/knowledge/child-process-argument-passing/>, <https://comcomponent.com/knowledge/unquoted-space-path-ambiguity/>, <https://comcomponent.com/knowledge/unintended-executable-launch/>, <https://comcomponent.com/knowledge/cmd-shell/>, <https://comcomponent.com/knowledge/bat-file/>, <https://comcomponent.com/knowledge/batch-file-command-injection/>, <https://comcomponent.com/knowledge/broken-argument-delivery/>, <https://comcomponent.com/knowledge/command-line-length-limit/>, <https://comcomponent.com/knowledge/response-file/>, <https://comcomponent.com/knowledge/argument-echo-exe/>, <https://comcomponent.com/knowledge/process-explorer/>, <https://comcomponent.com/knowledge/credential-in-command-line/>, <https://comcomponent.com/knowledge/command-line-startup-logging/>, <https://comcomponent.com/knowledge/secret-disclosure-in-logs/> .

<https://comcomponent.com/knowledge/windows-command-line-string/> a skos:Concept ;
    skos:prefLabel "コマンドライン文字列(lpCommandLine)"@ja ;
    skos:definition "Windowsがプロセスの起動時に渡す、実行ファイル名と引数を空白で並べた1本のnull終端文字列。引数の配列としては渡らず、受け取った側のプロセスが自分で分割する。上限は終端のnull文字を含めて32,767 UTF-16コード単位(サロゲートペアの文字は2つと数える)。"@ja ;
    skos:altLabel "lpCommandLine" ;
    skos:altLabel "コマンドライン"@ja .

<https://comcomponent.com/knowledge/command-line-backslash-quote-rule/> a skos:Concept ;
    skos:prefLabel "コマンドライン分割の規則(空白・引用符・バックスラッシュ)"@ja ;
    skos:definition "Windowsのコマンドライン文字列を引数に分割する規則。空白とタブで区切り、二重引用符で囲んだ範囲は区切らず、バックスラッシュは直後に二重引用符が来るときだけ特別扱いされる(2n個ならn個と囲みの開閉、2n+1個ならn個と文字としての引用符)。"@ja ;
    skos:altLabel "2n / 2n+1 バックスラッシュ規則"@ja .

<https://comcomponent.com/knowledge/argument-quoting-function/> a skos:Concept ;
    skos:prefLabel "引数の引用符付け(組み立て関数)"@ja ;
    skos:definition "引数の配列から、受け取り側の分割規則で元どおりに割れる1本のコマンドライン文字列を組み立てる処理。空白か引用符を含むか空の引数を引用符で囲み(空の引数は引用符2つだけになる)、引用符の直前のバックスラッシュを2倍+1、末尾のバックスラッシュを2倍にし、引用符にはバックスラッシュを前置する。往復が保証されるのは受け取り側がCommandLineToArgvW・Cランタイム・.NETランタイムと同じ分割規則でワイド文字のまま分割し(独自の文法で生のコマンドラインを解釈する相手や、途中にシェルのパーサが挟まる場合は対象外)、かつsetargv.obj/wsetargv.objによるワイルドカード展開を有効にしていない場合で(展開が有効だと*や?を含む引数がファイル名に置き換わる)、組み立てた文字列全体がCreateProcessのlpCommandLineの上限(終端のnull文字を含めて32,767 UTF-16コード単位)に収まることも前提になる。コマンドラインがnull終端文字列であるためNUL文字を含む引数は渡せず、狭い文字列のmainではコードページで表せない文字が失われる。"@ja ;
    skos:altLabel "ArgvQuote" ;
    skos:altLabel "コマンドラインの組み立て"@ja ;
    ks:prevents <https://comcomponent.com/knowledge/trailing-backslash-quote-pitfall/> ;
    ks:prevents <https://comcomponent.com/knowledge/doubled-quote-form/> .

<https://comcomponent.com/knowledge/processstartinfo-argumentlist/> a skos:Concept ;
    skos:prefLabel "ProcessStartInfo.ArgumentList"@ja ;
    skos:definition ".NET Core 2.1以降で、引数をコレクションとして個別に指定でき、必要な引用符付けをランタイムが行うProcessStartInfoのプロパティ。"@ja ;
    ks:implements <https://comcomponent.com/knowledge/argument-quoting-function/> ;
    ks:incompatibleWith <https://comcomponent.com/knowledge/processstartinfo-arguments-string/> .

<https://comcomponent.com/knowledge/createprocess/> a skos:Concept ;
    skos:prefLabel "CreateProcess"@ja ;
    skos:definition "新しいプロセスと主スレッドを作成するWin32 API。実行するモジュールをlpApplicationNameで、子プロセスに渡すコマンドライン文字列をlpCommandLineで指定する。"@ja ;
    skos:altLabel "CreateProcessW" ;
    skos:altLabel "CreateProcessA" .

<https://comcomponent.com/knowledge/lpapplicationname/> a skos:Concept ;
    skos:prefLabel "lpApplicationName"@ja ;
    skos:definition "CreateProcessの第1引数で、実行するモジュールのパスを明示する。NULLにするとlpCommandLineの先頭の空白区切りトークンから実行ファイルが推定され、モジュール名部分はMAX_PATHに制限される。"@ja .

<https://comcomponent.com/knowledge/getcommandlinew/> a skos:Concept ;
    skos:prefLabel "GetCommandLineW"@ja ;
    skos:definition "現在のプロセスに渡されたコマンドライン文字列全体を返すWin32 API。OSが実行ファイル名にフルパスを補うことがあるため、親がCreateProcessに渡した文字列と完全には一致しない場合がある。"@ja ;
    skos:altLabel "GetCommandLine" .

<https://comcomponent.com/knowledge/commandlinetoargvw/> a skos:Concept ;
    skos:prefLabel "CommandLineToArgvW"@ja ;
    skos:definition "Unicodeのコマンドライン文字列をCランタイムのargv/argcに似た配列に分割するWin32 API。戻り値は1回のLocalFreeで解放する。"@ja ;
    ks:implements <https://comcomponent.com/knowledge/command-line-backslash-quote-rule/> .

<https://comcomponent.com/knowledge/dotnet-command-line-segmentation/> a skos:Concept ;
    skos:prefLabel ".NETランタイムの引数分割"@ja ;
    skos:definition ".NETランタイムがWindowsでコマンドラインから引数配列を得る仕組み。apphostやdotnet.exeで起動した通常の構成では、ホスト自身がMSVCのCランタイムで作られたwmainのプログラムなので分割はCランタイム起動コードが行い、ホストは自分のオプションとアプリのパスを除いた残りを、アプリのパスと一緒にランタイムに渡す。ランタイムは起動時に、先頭にプログラム名(ホストから渡された起動名、無ければアセンブリのパス)を置いた配列を作ってEnvironment.GetCommandLineArgs用に保持し、Mainのargsにはプログラム名を除いた引数だけを渡す。起動時の引数を受け取らないホストされたライブラリの構成では、フォールバックとしてランタイム自身の分割コード(SegmentCommandLine)がGetCommandLineWの戻り値を分割する。この分割コードはMSVCのCランタイムの文書に合わせて実装され、CommandLineToArgvWは挙動がわずかに異なるため使っていない。ネイティブホストが独自のargc/argvを渡してMainを呼ぶ構成では、Mainのargsはホストが渡した値になる。"@ja ;
    skos:altLabel "SegmentCommandLine" ;
    skos:altLabel "Environment.GetCommandLineArgs" ;
    ks:implements <https://comcomponent.com/knowledge/command-line-backslash-quote-rule/> .

<https://comcomponent.com/knowledge/msvc-crt-argument-parsing/> a skos:Concept ;
    skos:prefLabel "Cランタイムの引数分割(argv生成)"@ja ;
    skos:definition "MSVCのCランタイム起動コードが、プログラム開始時にコマンドライン文字列をargc/argvへ分割する処理。Microsoft固有の規則に従い、既定ではワイルドカードを展開しない。"@ja ;
    skos:altLabel "MSVC起動コードのコマンドライン解析"@ja ;
    ks:configuredBy <https://comcomponent.com/knowledge/setargv-wildcard-expansion/> .

<https://comcomponent.com/knowledge/setargv-wildcard-expansion/> a skos:Concept ;
    skos:prefLabel "setargv.objによるワイルドカード展開"@ja ;
    skos:definition "MSVCのCランタイムで、setargv.obj(wmainならwsetargv.obj)をリンクすると、コマンドライン引数の*や?をファイル名に展開してargvへ入れるようになるオプション機能。既定では展開しない。"@ja ;
    skos:altLabel "wsetargv.obj" .

<https://comcomponent.com/knowledge/argv0-program-name-rule/> a skos:Concept ;
    skos:prefLabel "argv[0](プログラム名)の特別規則"@ja ;
    skos:definition "コマンドライン先頭のプログラム名だけに適用される分割規則。引用符で囲んで空白を含められるが、バックスラッシュによるエスケープは働かず、引用符そのものを含める方法もない。"@ja ;
    ks:requires <https://comcomponent.com/knowledge/windows-command-line-string/> .

<https://comcomponent.com/knowledge/trailing-backslash-quote-pitfall/> a skos:Concept ;
    skos:prefLabel "末尾バックスラッシュによる引数の巻き込み"@ja ;
    skos:definition "末尾がバックスラッシュのパスをそのまま引用符で囲むと、閉じ引用符が奇数個のバックスラッシュの直後に来て文字としての引用符と解釈され、囲みが閉じないまま後続の引数まで1つの引数として届く現象。"@ja .

<https://comcomponent.com/knowledge/doubled-quote-form/> a skos:Concept ;
    skos:prefLabel "囲みの内側の引用符2連続(非空の引数)"@ja ;
    skos:definition "引用符で囲まれた中身のある引数の内側に二重引用符を2つ隣接させ、1つの引用符を表す書き方。空の引数を表す引用符2つだけの形とは別物。MSVCのCランタイムの規則には含まれるが、CommandLineToArgvWの公式の規則にはなく、2008年より前と後のVCで解釈が異なる。"@ja .

<https://comcomponent.com/knowledge/processstartinfo-arguments-string/> a skos:Concept ;
    skos:prefLabel "ProcessStartInfo.Arguments(手組み文字列)"@ja ;
    skos:definition "引用符付けを自分で行った1本のコマンドライン文字列として引数を渡す、ProcessStartInfoの旧来のプロパティ。"@ja .

<https://comcomponent.com/knowledge/child-process-argument-passing/> a skos:Concept ;
    skos:prefLabel "子プロセスへの引数の受け渡し"@ja ;
    skos:definition "呼び出し側が子プロセスに引数を渡す行為。Windowsでは配列ではなく1本のコマンドライン文字列として渡るため、受け取り側の分割規則で元どおりに割れる文字列を組み立てることと同義になる。"@ja ;
    skos:altLabel "コマンドライン引数の受け渡し"@ja ;
    ks:verifiedBy <https://comcomponent.com/knowledge/process-explorer/> .

<https://comcomponent.com/knowledge/unquoted-space-path-ambiguity/> a skos:Concept ;
    skos:prefLabel "空白を含む実行ファイルパスの曖昧さ(Program.exe問題)"@ja ;
    skos:definition "lpApplicationNameをNULLにして空白を含むパスを引用符なしでコマンドライン先頭に置くと、CreateProcessが短い候補(C:\\Program.exeなど)から順に実行ファイルを試すため、意図しないファイルが実行され得る状態。"@ja ;
    skos:altLabel "Program.exe問題"@ja .

<https://comcomponent.com/knowledge/unintended-executable-launch/> a skos:Concept ;
    skos:prefLabel "意図しない実行ファイルの起動"@ja ;
    skos:definition "呼び出し側が起動しようとしたものとは別の実行ファイルが、パスの解釈や探索順序の結果として起動されてしまうこと。"@ja .

<https://comcomponent.com/knowledge/bat-file/> a skos:Concept ;
    skos:prefLabel "バッチファイル(bat)"@ja ;
    skos:definition "cmd.exeが解釈するコマンドを並べたスクリプトファイル。拡張子.batまたは.cmdを持つ。"@ja ;
    skos:altLabel "bat" ;
    skos:altLabel "cmdスクリプト"@ja .

<https://comcomponent.com/knowledge/batch-file-command-injection/> a skos:Concept ;
    skos:prefLabel "バッチファイル経由のコマンド注入リスク"@ja ;
    skos:definition "バッチファイル(.bat/.cmd)への引数が生のコマンドライン文字列としてcmd.exeへ渡ることを悪用した、コマンド注入につながり得るリスク。"@ja .

<https://comcomponent.com/knowledge/cmd-shell/> a skos:Concept ;
    skos:prefLabel "コマンドシェル(cmd.exe)"@ja ;
    skos:definition "Windowsに搭載される、batファイルなどのバッチスクリプトを実行する伝統的なコマンドラインシェル。"@ja ;
    skos:altLabel "cmd" ;
    skos:altLabel "コマンドプロンプト"@ja .

<https://comcomponent.com/knowledge/broken-argument-delivery/> a skos:Concept ;
    skos:prefLabel "引用符消失・空文字列引数の消失"@ja ;
    skos:definition "解析済みの引数がスペース区切りの1本の文字列に組み立て直される過程で、埋め込まれた引用符が失われたり空文字列の引数が消えたりする現象。"@ja .

<https://comcomponent.com/knowledge/response-file/> a skos:Concept ;
    skos:prefLabel "応答ファイル"@ja ;
    skos:definition "引数の内容をファイルに書き出し、コマンドラインにはそのファイルのパスだけを渡す方式。コマンドライン長の上限を回避するための公式の回避策の一つだが、CreateProcessやcmd.exeがファイルを展開するわけではなく、受け取るプログラムが@fileのような構文で応答ファイルを読めることが前提になる。"@ja ;
    skos:altLabel "レスポンスファイル"@ja ;
    skos:altLabel "パラメーターファイル"@ja .

<https://comcomponent.com/knowledge/command-line-length-limit/> a skos:Concept ;
    skos:prefLabel "コマンドライン長の上限"@ja ;
    skos:definition "コマンドライン文字列に課される長さの上限。CreateProcessのlpCommandLineは終端のnull文字を含めて32,767 UTF-16コード単位(サロゲートペアの文字は2つと数える)、cmd.exeのコマンドラインとバッチファイル内の行は8,191文字、.NETのProcessStartInfo.Argumentsは文字列長(UTF-16コード単位)が32,699未満。"@ja ;
    skos:altLabel "32,767 UTF-16コード単位"@ja ;
    skos:altLabel "8,191文字"@ja .

<https://comcomponent.com/knowledge/argument-echo-exe/> a skos:Concept ;
    skos:prefLabel "引数表示用の確認exe"@ja ;
    skos:definition "受け取ったコマンドライン文字列と分割後の引数配列を1件1行で表示するだけの小さな実行ファイル。改行や制御文字を含む引数でも行が崩れないよう、各値はJSON文字列として可逆にエスケープし、長さ(UTF-16コード単位)を添えて出力する。相手のexeの代わりに起動して、実際に届いた引数を確認するために使う。パーサは複数系統あり端の形で解釈が分かれるため、確認したい相手と同じランタイム(MSVCのC/C++か.NETか)で作る必要がある。"@ja ;
    skos:altLabel "引数エコープログラム"@ja .

<https://comcomponent.com/knowledge/process-explorer/> a skos:Concept ;
    skos:prefLabel "Process Explorer"@ja ;
    skos:definition "プロセスに読み込まれているDLLだけでなく、ハンドル・スレッドスタック・GDI/USERオブジェクト数なども確認できるSysinternalsのプロセス監視ツール。管理者として実行すると他ユーザーやサービスのプロセスも参照できる。"@ja .

<https://comcomponent.com/knowledge/command-line-startup-logging/> a skos:Concept ;
    skos:prefLabel "コマンドラインのログ記録(呼び出し側・起動時)"@ja ;
    skos:definition "呼び出し側が組み立てたコマンドライン文字列、または起動したプログラムが受け取ったコマンドライン文字列や分割後の引数をログに書き出す運用。どんな文字列で起動されたかを後から確認できるが、記録の仕方によっては引数に含まれる機密がログに残る。"@ja ;
    skos:altLabel "起動引数のログ"@ja ;
    skos:altLabel "起動時のコマンドラインのログ記録"@ja .

<https://comcomponent.com/knowledge/secret-disclosure-in-logs/> a skos:Concept ;
    skos:prefLabel "ログへの機密の漏えい"@ja ;
    skos:definition "パスワード・APIキー・トークンなどの機密がアプリケーションログや集約ログに書き込まれ、プロセスより長い期間、より広い範囲の閲覧者に対して残ってしまう状態。"@ja ;
    skos:altLabel "ログに残った資格情報"@ja .

<https://comcomponent.com/knowledge/credential-in-command-line/> a skos:Concept ;
    skos:prefLabel "コマンドライン引数への機密の混入"@ja ;
    skos:definition "パスワードやAPIキーをコマンドライン引数として渡す実装。プロセスの引数を読める相手にはその機密が渡る。"@ja .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/createprocess/> ;
    rdf:predicate ks:uses ;
    rdf:object <https://comcomponent.com/knowledge/windows-command-line-string/> ;
    schema:description "CreateProcessは引数の配列ではなく、lpCommandLineという1本のnull終端文字列を受け取り、それが新しいプロセスに渡る。ただし先頭の実行ファイル名はOSがフルパスを補うことがあるため、子がGetCommandLineWで見る文字列は親が渡した文字列と完全には一致しない場合がある。Unicode版はこの文字列を書き換えることがあるため、読み取り専用のバッファは渡せない。"@ja ;
    ks:evidence <https://learn.microsoft.com/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessw> ;
    ks:verifiedAt "2026-09-02" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/createprocess/> ;
    rdf:predicate ks:uses ;
    rdf:object <https://comcomponent.com/knowledge/lpapplicationname/> ;
    schema:description "lpApplicationNameにNULL以外を渡した場合、CreateProcessは実行するモジュールをlpApplicationNameで確定し、子のargv[0]はlpCommandLineの先頭トークンで決まる。NULLを渡した場合はこの引数は使われず、lpCommandLineの先頭トークンから実行モジュールを解決する。"@ja ;
    ks:evidence <https://learn.microsoft.com/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessw> ;
    ks:verifiedAt "2026-09-02" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/windows-command-line-string/> ;
    rdf:predicate ks:verifiedBy ;
    rdf:object <https://comcomponent.com/knowledge/getcommandlinew/> ;
    schema:description "子プロセスは自分に渡されたコマンドライン文字列全体をGetCommandLineWで取り出せる。起動時にこの値をログに残しておくと、どんな文字列で起動されたかを後から確認できるが、引数にパスワードやトークンが含まれる設計ではそのまま保存せず、分割後に機密になり得る値を伏せ字にして記録するか、生の記録は限定した診断モードでだけ有効にする。cmd.exeやバッチが挟まっている場合、見えるのはその段が作り直した文字列で、呼び出し側の元の文字列は呼び出し側のログでしか分からない。"@ja ;
    ks:evidence <https://learn.microsoft.com/windows/win32/api/processenv/nf-processenv-getcommandlinew> ;
    ks:verifiedAt "2026-09-02" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/commandlinetoargvw/> ;
    rdf:predicate ks:uses ;
    rdf:object <https://comcomponent.com/knowledge/getcommandlinew/> ;
    schema:description "CommandLineToArgvWは呼び出し側が渡した任意のコマンドライン文字列を分割する関数で、GetCommandLineWを自分で呼ぶわけではない。受け取り側で自分の引数を得る典型的な使い方として、GetCommandLineWの戻り値をCommandLineToArgvWに渡すとargv形式の配列が得られる。"@ja ;
    ks:evidence <https://learn.microsoft.com/windows/win32/api/processenv/nf-processenv-getcommandlinew>, <https://learn.microsoft.com/windows/win32/api/shellapi/nf-shellapi-commandlinetoargvw> ;
    ks:verifiedAt "2026-09-02" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/dotnet-command-line-segmentation/> ;
    rdf:predicate ks:uses ;
    rdf:object <https://comcomponent.com/knowledge/getcommandlinew/> ;
    schema:description "ランタイム自身の分割コード(SegmentCommandLine)がGetCommandLineWの戻り値を分割するのは、起動時の引数を受け取らないホストされたライブラリの構成でのフォールバックに限られる。apphostやdotnet.exeで起動した通常の構成では、ホストのCランタイム起動コードが分割し、ホスト用オプションとアプリのパスを除いた引数をランタイムが起動時に受け取り、先頭にプログラム名を足した配列をGetCommandLineArgs用に保持し、Mainのargsにはプログラム名を除いた引数を渡すため、ランタイム自身はGetCommandLineWを分割しない。ネイティブホストが独自のargc/argvを渡す構成でもMainのargsはホストが渡した値になる。"@ja ;
    ks:evidence <https://github.com/dotnet/runtime/blob/main/src/libraries/System.Private.CoreLib/src/System/Environment.cs>, <https://github.com/dotnet/runtime/blob/main/src/libraries/System.Private.CoreLib/src/System/Environment.Windows.cs>, <https://github.com/dotnet/runtime/blob/main/src/native/corehost/apphost/apphost.c>, <https://github.com/dotnet/runtime/blob/main/src/coreclr/vm/corhost.cpp> ;
    ks:verifiedAt "2026-09-03" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/commandlinetoargvw/> ;
    rdf:predicate ks:implements ;
    rdf:object <https://comcomponent.com/knowledge/command-line-backslash-quote-rule/> ;
    schema:description "CommandLineToArgvWは、引用符の中モードの切り替えと、二重引用符の直前のバックスラッシュを2n個ならn個と囲みの開閉、2n+1個ならn個と文字の引用符として扱う規則で文字列を分割する。"@ja ;
    ks:evidence <https://learn.microsoft.com/windows/win32/api/shellapi/nf-shellapi-commandlinetoargvw> ;
    ks:verifiedAt "2026-09-02" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/msvc-crt-argument-parsing/> ;
    rdf:predicate ks:implements ;
    rdf:object <https://comcomponent.com/knowledge/command-line-backslash-quote-rule/> ;
    schema:description "MSVCのCランタイム起動コードは、空白とタブによる区切り、引用符による囲み、偶数個・奇数個のバックスラッシュと引用符の規則に従ってargvを作る。mainではargvが現在のコードページに変換された狭い文字列になるため、コードページで表せない文字は失われる。"@ja ;
    ks:evidence <https://learn.microsoft.com/cpp/cpp/main-function-command-line-args> ;
    ks:verifiedAt "2026-09-02" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/dotnet-command-line-segmentation/> ;
    rdf:predicate ks:implements ;
    rdf:object <https://comcomponent.com/knowledge/command-line-backslash-quote-rule/> ;
    schema:description ".NETランタイム自身の分割コードは、MSVCのmain関数のドキュメントに記された規則に従って実装されている。apphostやdotnet.exeで起動した通常の構成ではホストのCランタイム起動コードが同じ規則で分割する。Environment.GetCommandLineArgsのドキュメントも同じバックスラッシュと引用符の規則を示している。"@ja ;
    ks:evidence <https://github.com/dotnet/runtime/blob/main/src/libraries/System.Private.CoreLib/src/System/Environment.Windows.cs>, <https://learn.microsoft.com/dotnet/api/system.environment.getcommandlineargs> ;
    ks:verifiedAt "2026-09-02" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/msvc-crt-argument-parsing/> ;
    rdf:predicate ks:configuredBy ;
    rdf:object <https://comcomponent.com/knowledge/setargv-wildcard-expansion/> ;
    schema:description "Cランタイムの引数分割は既定ではワイルドカードを展開しないが、setargv.obj(wmainならwsetargv.obj)をリンクすると*や?をファイル名に展開するようになる。"@ja ;
    ks:evidence <https://learn.microsoft.com/cpp/cpp/main-function-command-line-args> ;
    ks:verifiedAt "2026-09-02" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/argv0-program-name-rule/> ;
    rdf:predicate ks:requires ;
    rdf:object <https://comcomponent.com/knowledge/windows-command-line-string/> ;
    schema:description "コマンドライン文字列の先頭トークン(argv[0])は、ファイルシステムのパスとして妥当であることを前提に、引用符で囲めるがバックスラッシュのエスケープ規則は適用されないという別扱いを受ける。"@ja ;
    ks:evidence <https://learn.microsoft.com/cpp/cpp/main-function-command-line-args>, <https://learn.microsoft.com/windows/win32/api/shellapi/nf-shellapi-commandlinetoargvw> ;
    ks:verifiedAt "2026-09-02" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/command-line-backslash-quote-rule/> ;
    rdf:predicate ks:mayCause ;
    rdf:object <https://comcomponent.com/knowledge/trailing-backslash-quote-pitfall/> ;
    schema:description "末尾がバックスラッシュのパスをそのまま引用符で囲むと、閉じ引用符の直前が奇数個のバックスラッシュになり、引用符が文字として解釈されて囲みが閉じず、後続の引数まで1つに巻き込まれる。空白を含まず引用符で囲まない場合は起きない。"@ja ;
    ks:evidence <https://learn.microsoft.com/windows/win32/api/shellapi/nf-shellapi-commandlinetoargvw>, <https://learn.microsoft.com/cpp/cpp/main-function-command-line-args> ;
    ks:verifiedAt "2026-09-02" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/argument-quoting-function/> ;
    rdf:predicate ks:prevents ;
    rdf:object <https://comcomponent.com/knowledge/trailing-backslash-quote-pitfall/> ;
    schema:description "組み立て関数は引用符で囲む引数の末尾のバックスラッシュを2倍にして偶数個にするため、閉じ引用符が正しく囲みを終了させ、後続の引数を巻き込まない。"@ja ;
    ks:evidence <https://github.com/dotnet/runtime/blob/main/src/libraries/System.Private.CoreLib/src/System/PasteArguments.cs> ;
    ks:verifiedAt "2026-09-02" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/argument-quoting-function/> ;
    rdf:predicate ks:prevents ;
    rdf:object <https://comcomponent.com/knowledge/doubled-quote-form/> ;
    schema:description "組み立て関数は引数中の引用符に必ずバックスラッシュを前置するため、中身のある引数の内側で引用符が隣接する形を生成しない。この形は2008年より前と後のVCで解釈が異なるため、.NETの組み立てコードも意図的に避けている。空の引数を表す引用符2つだけの形はこれとは別で、正しく生成される。"@ja ;
    ks:evidence <https://github.com/dotnet/runtime/blob/main/src/libraries/System.Private.CoreLib/src/System/PasteArguments.cs> ;
    ks:verifiedAt "2026-09-02" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/processstartinfo-argumentlist/> ;
    rdf:predicate ks:implements ;
    rdf:object <https://comcomponent.com/knowledge/argument-quoting-function/> ;
    schema:description "ProcessStartInfo.ArgumentListは追加された要素ごとに引用符付けとエスケープを行い、内部で1本の文字列に組み立ててからOSに渡す。その規則は空白も引用符も含まない引数はそのまま、それ以外は引用符で囲み、引用符の直前のバックスラッシュを2倍+1、末尾を2倍にするというもの。"@ja ;
    ks:evidence <https://learn.microsoft.com/dotnet/api/system.diagnostics.processstartinfo.argumentlist>, <https://github.com/dotnet/runtime/blob/main/src/libraries/System.Private.CoreLib/src/System/PasteArguments.cs> ;
    ks:verifiedAt "2026-09-02" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/processstartinfo-arguments-string/> ;
    rdf:predicate ks:requires ;
    rdf:object <https://comcomponent.com/knowledge/argument-quoting-function/> ;
    schema:description "UseShellExecute=falseで実行ファイルを直接起動し、受け取り側が公開された分割規則で解釈する場合、ProcessStartInfo.Argumentsは自分で組み立てた1本の文字列をそのまま渡すため、呼び出し側が分割規則に沿った引用符付けを行う必要がある(ArgumentListのない.NET Frameworkでは同じ規則の関数で組み立てる)。UseShellExecute=trueで文書やURLを開く場合はシェルの関連付けがハンドラのコマンドラインを組み立てるため、この関数だけでは足りない。"@ja ;
    ks:evidence <https://learn.microsoft.com/dotnet/api/system.diagnostics.processstartinfo.arguments>, <https://learn.microsoft.com/dotnet/api/system.diagnostics.processstartinfo.argumentlist> ;
    ks:verifiedAt "2026-09-02" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/processstartinfo-argumentlist/> ;
    rdf:predicate ks:incompatibleWith ;
    rdf:object <https://comcomponent.com/knowledge/processstartinfo-arguments-string/> ;
    schema:description "ArgumentListとArgumentsは互いに独立していて、同時には使えない。片方を使うときはもう片方が空でなければならない。"@ja ;
    ks:evidence <https://learn.microsoft.com/dotnet/api/system.diagnostics.processstartinfo.argumentlist>, <https://learn.microsoft.com/dotnet/api/system.diagnostics.processstartinfo.arguments> ;
    ks:verifiedAt "2026-09-02" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/processstartinfo-argumentlist/> ;
    rdf:predicate ks:recommendedFor ;
    rdf:object <https://comcomponent.com/knowledge/child-process-argument-passing/> ;
    schema:description ".NET Core 2.1以降から子プロセスを起動するときは、1要素を1引数としてArgumentListに追加する方法を本記事は推奨している。公式ドキュメントも、引用符付けに自信がなければArgumentListを選ぶよう案内している。"@ja ;
    ks:evidence <https://learn.microsoft.com/dotnet/api/system.diagnostics.processstartinfo.argumentlist> ;
    ks:verifiedAt "2026-09-02" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/argument-quoting-function/> ;
    rdf:predicate ks:recommendedFor ;
    rdf:object <https://comcomponent.com/knowledge/child-process-argument-passing/> ;
    schema:description "C++や.NET Frameworkのように組み立てを自分で行い、実行ファイルを直接起動して、受け取り側がCommandLineToArgvW・Cランタイム・.NETランタイムの分割規則で解釈する場合に、引用符を手で書かず、分割規則の逆写像となる1つの関数で全引数を組み立てることを本記事は推奨している。cmd.exeやバッチファイルを経由する場合は別のパーサが挟まるため、この関数だけでは足りない。"@ja ;
    ks:evidence <https://learn.microsoft.com/windows/win32/api/shellapi/nf-shellapi-commandlinetoargvw>, <https://learn.microsoft.com/cpp/cpp/main-function-command-line-args> ;
    ks:verifiedAt "2026-09-02" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/lpapplicationname/> ;
    rdf:predicate ks:prevents ;
    rdf:object <https://comcomponent.com/knowledge/unquoted-space-path-ambiguity/> ;
    schema:description "lpApplicationNameに実行ファイルのフルパスを渡した場合に限り、実行するモジュールはコマンドライン文字列の先頭トークンの解釈に依存しなくなる。NULLを渡した場合はlpCommandLineの先頭から推定されるため曖昧さは残る。公式ドキュメントはNULLを渡さないこと、渡す場合は先頭のパスを引用符で囲むことを求めている。"@ja ;
    ks:evidence <https://learn.microsoft.com/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessw> ;
    ks:verifiedAt "2026-09-02" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/unquoted-space-path-ambiguity/> ;
    rdf:predicate ks:mayCause ;
    rdf:object <https://comcomponent.com/knowledge/unintended-executable-launch/> ;
    schema:description "空白を含むパスを引用符なしで先頭に置くと、CreateProcessはC:\\Program.exeのような短い候補から順に存在を試すため、そこに別の実行ファイルが置かれていればそれが起動する。"@ja ;
    ks:evidence <https://learn.microsoft.com/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessw> ;
    ks:verifiedAt "2026-09-02" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/bat-file/> ;
    rdf:predicate ks:mayCause ;
    rdf:object <https://comcomponent.com/knowledge/batch-file-command-injection/> ;
    schema:description "バッチファイルは引数を分割せず生のコマンドライン文字列としてcmd.exeに渡すため、外から来た値をそのまま渡すとコマンド注入の余地が生じる。公式ドキュメントは信頼できない入力をバッチファイルに渡さないよう警告している。"@ja ;
    ks:evidence <https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_parsing> ;
    ks:verifiedAt "2026-09-02" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/cmd-shell/> ;
    rdf:predicate ks:mayCause ;
    rdf:object <https://comcomponent.com/knowledge/broken-argument-delivery/> ;
    schema:description "cmd.exeは&、|、丸括弧などを構文として扱い、/cや/kに続く文字列の外側の引用符を条件によって剥がすため、分割規則に沿って引用符付けした文字列でも引数が変形して届くことがある。"@ja ;
    ks:evidence <https://learn.microsoft.com/windows-server/administration/windows-commands/cmd> ;
    ks:verifiedAt "2026-09-02" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/response-file/> ;
    rdf:predicate ks:mitigates ;
    rdf:object <https://comcomponent.com/knowledge/command-line-length-limit/> ;
    schema:description "件数に比例して伸びる引数は、内容をファイルに書き出してそのパスだけを渡す応答ファイル方式にすれば、cmd.exeの8,191文字やCreateProcessの32,767 UTF-16コード単位の上限に達しない。ただしCreateProcessもcmd.exeもファイルを展開しないため、受け取るプログラムが@fileのような構文で応答ファイルを読めるか、読めるように直せる場合に限られる。"@ja ;
    ks:evidence <https://learn.microsoft.com/troubleshoot/windows-client/shell-experience/command-line-string-limitation> ;
    ks:verifiedAt "2026-09-02" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/child-process-argument-passing/> ;
    rdf:predicate ks:verifiedBy ;
    rdf:object <https://comcomponent.com/knowledge/argument-echo-exe/> ;
    schema:description "相手のexeの代わりに引数表示用のexeを起動すると、分割後の配列に何が届いたかを直接確認できる。ただし表示用exeは相手と同じランタイム(MSVCのC/C++か.NETか)で作らないと、囲みの中の引用符2連続のような端の形で解釈が食い違う。相手が自分たちのプログラムなら、相手自身の起動時にargvをログに残すほうが確実。"@ja ;
    ks:evidence <https://learn.microsoft.com/dotnet/api/system.environment.getcommandlineargs> ;
    ks:verifiedAt "2026-09-02" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/child-process-argument-passing/> ;
    rdf:predicate ks:verifiedBy ;
    rdf:object <https://comcomponent.com/knowledge/process-explorer/> ;
    schema:description "Process Explorerのプロセスのプロパティには子プロセスが保持しているコマンドライン文字列が表示されるため、相手側に届いた文字列を確認できる。ただし先頭の実行ファイル名はOSがフルパスを補っていることがあり、cmd.exeやバッチが挟まっていれば見えるのはその段が作り直した文字列で、呼び出し側のバッファと一致するとは限らない。分割後の配列は分からない。"@ja ;
    ks:evidence <https://learn.microsoft.com/sysinternals/downloads/process-explorer> ;
    ks:verifiedAt "2026-09-02" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/command-line-startup-logging/> ;
    rdf:predicate ks:uses ;
    rdf:object <https://comcomponent.com/knowledge/getcommandlinew/> ;
    schema:description "起動したプログラム側でコマンドラインをログに記録する場合は、GetCommandLineWが返す文字列(または分割後の引数)を材料にする。呼び出し側のログは起動前のバッファやArgumentListの要素を材料にするため、GetCommandLineWは使わない。"@ja ;
    ks:evidence <https://learn.microsoft.com/windows/win32/api/processenv/nf-processenv-getcommandlinew> ;
    ks:verifiedAt "2026-09-02" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/command-line-startup-logging/> ;
    rdf:predicate ks:mayCause ;
    rdf:object <https://comcomponent.com/knowledge/secret-disclosure-in-logs/> ;
    schema:description "呼び出し側で組み立てた文字列でも、起動したプログラムがGetCommandLineWで受け取った文字列でも、そのままログに保存すると、引数にパスワード・APIキー・トークンが含まれている場合にそれがログに残る。ログはプロセスより長く保持され、より多くの人が閲覧するため、どちら側でも機密になり得る値を伏せ字にしてから記録するか、生の記録を限定した診断モードに閉じ込める必要がある。"@ja ;
    ks:evidence <https://learn.microsoft.com/windows/win32/api/processenv/nf-processenv-getcommandlinew>, <https://cheatsheetseries.owasp.org/cheatsheets/Logging_Cheat_Sheet.html> ;
    ks:verifiedAt "2026-09-02" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/credential-in-command-line/> ;
    rdf:predicate ks:mayCause ;
    rdf:object <https://comcomponent.com/knowledge/secret-disclosure-in-logs/> ;
    schema:description "引数にパスワードやトークンを渡す設計では、起動時のコマンドラインの記録やプロセス監視ツールの表示を通じて、その値がログに残り得る。ログ側で伏せ字にするだけでなく、機密を引数で渡さない設計が根本の対策になる。"@ja ;
    ks:evidence <https://cheatsheetseries.owasp.org/cheatsheets/Logging_Cheat_Sheet.html> ;
    ks:verifiedAt "2026-09-02" ;
    ks:certainty "context-dependent" .
