コマンドライン文字列の最大長


110

Windowsでは、コマンドライン文字列の最大長はいくつですか?次のようなコマンドラインで引数を取るプログラムを指定した場合の意味abc.exe -name=abc

私が書いたシンプルなコンソールアプリケーションは、コマンドラインを介してパラメーターを取り、最大許容量を知りたいと思っています。


誰か興味があれば、私はプログラムがより長いコマンドラインをサポートする方法に取り組んでます。十分なサポートを構築できると仮定すると、Microsoftが何かを修正する必要がなく、直接互換性のある方法で、制限が完全に削除されます。質問への回答ではありませんが、IMOへのリンクを用意しておく価値はあります。
alastair

回答:


87

Microsoftのドキュメントから:コマンドプロンプト(Cmd.exe)コマンドライン文字列の制限

Microsoft Windows XP以降を実行しているコンピューターでは、コマンドプロンプトで使用できる文字列の最大長は8191文字です。


33
これは、(質問ごとに)コマンドプロンプトから実際に実行されるプログラムにのみ適用されます。ショートカット(.LNK)を約2048に260文字、32767へのCreateProcess、およびShellExecuteをに限定されている主題のレイモンド陳氏の記事によると
NtscCobalt

2 ^ 13-1文字。これは、何かが16の数値で追跡され、これが13ビットを使用することを意味します。他の3ビットは何のためにあるのでしょうか。
Sqeaky 2016年

@ulrichbそして、そのリンクは、さらに別のブログの移行後にも壊れています。引用された記事は、devblogs.microsoft.com / oldnewthing / 20031210-00 /?p
Adam Rosenfieldの

72

古いスレッドを掘り下げてすみませんが、sunetosの答えは正しくない(または完全な答えではない)と思います。(c#でProcessStartInfoを使用して)いくつかの実験を行いましたが、コマンドラインコマンドの「引数」文字列は、XPでは2048文字、Win7では32768文字に制限されているようです。8191の制限が何を指しているのかはわかりませんが、その証拠はまだ見つかっていません。


Win7の32kの数値はどこで入手できますか?その情報源が見つかりません。環境ブロックのサイズを考えていますか?
ポップ

1
たぶん。C#ProcessStartInfoクラスを介して、より長い引数をプロセスに渡すことにより、32kの数値を見つけました。32kの後で例外をスローします。
Sugrue

10
@ LordTorgamus、32kの制限は、UNICODE_STRING構造(ushort長)によるものです。件名に関するRaymond Chenの記事によると、 CMD
は行

1
Windows 10のPowerShellについてはどうですか?
Nilzor

1
cmdなどの8191は非常に現実的なようです
。MSBuildで

41

@Sugrueとして、私も古いスレッドを掘り出しています。

32768(32767である必要があると思いますが、実験的なテスト結果を信じさせます)文字制限がある理由を説明するために、Windows APIを掘り下げる必要があります。

コマンドライン引数を使用してプログラムをどのように起動しても、ShellExecuteCreateProcessまたはそれらの拡張バージョンに渡されます。これらのAPIは、公式に文書化されていない他のNTレベルのAPIを基本的にラップします。私の知る限り、これらの呼び出しはNtCreateProcessをラップします。これには、パラメーターとしてOBJECT_ATTRIBUTES構造体が必要であり、その構造体を作成するためにInitializeObjectAttributesが使用されます。この場所で見るUNICODE_STRING。それでは、この構造を見てみましょう:

typedef struct _UNICODE_STRING {
    USHORT Length;
    USHORT MaximumLength;
    PWSTR  Buffer;
} UNICODE_STRING;

これは、使用USHORTストア長さに変数を、(16ビット長[65535 0])。そしてよると、この、長さはバイトではなく文字数で大きさを示しています。したがって、次のようになります65535 / 2 = 32767WCHAR長さが2バイトであるため)。

この数を掘り下げるにはいくつかの手順がありますが、それが明確であることを願っています。


また、@ sunetosをサポートするために、受け入れられるものに答えてください。8191はに入力できる最大数です。cmd.exeこの制限を超えると、The input line is too long.エラーが生成されます。したがって、cmd.exe新しいプロセスに引数を渡す唯一の方法ではないという事実にもかかわらず、答えは正しいです。


ヌル終了ストリングが保管されるため、長さは最大32,766文字です。
Eryk Sun

1
プロセスはオブジェクトの名前空間で名前が付けられていないため、ObjectAttributesはセキュリティ記述子にのみ使用され、返されるハンドルを継承可能にします。コマンドラインはProcessParameters、プロセス環境ブロック(PEB)によって参照されるで渡されます。古いバージョンではNtCreateProcess、これらのパラメータはを介して子プロセスに書き込む必要がありますNtWriteVirtualMemory。今日ではNtCreateUserProcess、いくつかの単一のカーネル・サービスの呼び出し組み合わせた、使用されている-例えば作成SectionProcessおよびThreadオブジェクトを、そして、プロセスパラメータを書きます。
Eryk Sun

@eryksun UNICODE_STRING構造体は、必ずしもnullターミネータを格納するわけではありません。
マイクロソフトジャッキー

明らかに、カウントされた文字列は、必ずしもnullで終了する文字列を使用するわけではありません。たとえば、NTAPIレジストリ関数を使用すると、nullが含まれるキー名を作成してアクセスできますが、nullで終了する文字列を使用するWINAPIレジストリ関数ではアクセスできません。同様に、WINAPI CreateProcessWはコマンドラインとアプリケーションパスにnullで終了する文字列を使用します。制限は32,767-1、つまり32,766文字です。
Eryk Sun

@eryksun MSDNのレジストリエレメントサイズの制限に関するドキュメントで、レジストリキー名の最大長は255文字であることがわかりましたが、実際には256文字のキー名を作成できます。Cスタイルの文字列は長さの制限のない単なるポインタなので、32,767文字の文字列をUnicode関数に渡すことができる可能性があるためCreateProcessWUNICODE_STRING構造体に正確な長さを格納し、両方LengthMaximumLength65,534に設定する場合があります、それはの正当な議論ですNtCreateProcess
賈可可Jacky

3

Windows 10では、8191文字のままです...少なくとも私のマシンでは。

8191文字の後のテキストを切り捨てるだけです。ええと、実際には、8196文字を取得しました。8196を超えると、入力できなくなります。

次のスクリプトは、使用できるステートメントの長さをテストします。まあ、gawk / awkがインストールされているとしましょう。

echo rem this is a test of how long of a line that a .cmd script can generate >testbat.bat
gawk 'BEGIN {printf "echo -----";for (i=10;i^<=100000;i +=10) printf "%%06d----",i;print;print "pause";}' >>testbat.bat
testbat.bat

それがcmd.exeの制限です。上記の回答にあるように、UNICODE_STRINGのため、実際の制限は32,768文字です。
alastair
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.