141

In Windows, what is the maximum length of a command line string? Meaning if I specify a program which takes arguments on the command line such as abc.exe -name=abc

A simple console application I wrote takes parameters via command line and I want to know what is the maximum allowable amount.

1

4 Answers 4

111

From the Microsoft documentation: Command prompt (Cmd. exe) command-line string limitation

On computers running Microsoft Windows XP or later, the maximum length of the string that you can use at the command prompt is 8191 characters.

Sign up to request clarification or add additional context in comments.

4 Comments

2^13-1 characters, that implies something is tracked in a 16 number and this uses 13 of those bits. I wonder what the other 3 bits are for?
@ulrichb And now that link is broken too after yet another blog migration. The cited article can now be found at devblogs.microsoft.com/oldnewthing/20031210-00/?p=41553
How long is the limit now with Windows 11 and the new Windows Terminal? I hope they increased it. Passing tens of thousands files with long paths to CMake is taking megabytes. Should be unlimited.
there is a confusion of cmd.exe limit and general process invocation limit. CMake does not run cmd.exe normally, and you shouldn't be executing it via cmd.exe either (most likely you'll use cygwin or mingw bash, or at least powershell). For both limits it's irrelevant if you use the old command prompt host, the new Terminal app, or mintty from mingw. See @ST3 answer below for the general limit.
77

Sorry for digging out an old thread, but I think sunetos' answer isn't correct (or isn't the full answer). I've done some experiments (using ProcessStartInfo in c#) and it seems that the 'arguments' string for a commandline command is limited to 2048 characters in XP and 32768 characters in Win7. I'm not sure what the 8191 limit refers to, but I haven't found any evidence of it yet.

10 Comments

Where'd you get the 32k figure for Win7? I can't find a source for that. Are you thinking of the size of the environment block?
Possibly. I found the 32k figure by passing longer and longer arguments to a process via C# ProcessStartInfo class. It throws an exception after 32k.
@LordTorgamus, The 32k limit is due to the UNICODE_STRING structure (ushort length). According to Raymond Chen's article on the subject CMD limits lines to 8192 characters (I'd assume the carrage return is the final character) and ShellExecuteEx limits to "INTERNET_MAX_URL_LENGTH (around 2048)"
What about under PowerShell on Windows 10?
8191 for cmd and the likes seems very real, just ran into this when running a very long command via Exec in MSBuild
|
56

As @Sugrue I'm also digging out an old thread.

To explain why there is 32768 (I think it should be 32767, but lets believe experimental testing result) characters limitation we need to dig into Windows API.

No matter how you launch program with command line arguments it goes to ShellExecute, CreateProcess or any extended their version. These APIs basically wrap other NT level API that are not officially documented. As far as I know these calls wrap NtCreateProcess, which requires OBJECT_ATTRIBUTES structure as a parameter, to create that structure InitializeObjectAttributes is used. In this place we see UNICODE_STRING. So now lets take a look into this structure:

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

It uses USHORT (16-bit length [0; 65535]) variable to store length. And according this, length indicates size in bytes, not characters. So we have: 65535 / 2 = 32767 (because WCHAR is 2 bytes long).

There are a few steps to dig into this number, but I hope it is clear.


Also, to support @sunetos answer what is accepted. 8191 is a maximum number allowed to be entered into cmd.exe, if you exceed this limit, The input line is too long. error is generated. So, answer is correct despite the fact that cmd.exe is not the only way to pass arguments for new process.

8 Comments

The length is up to 32,766 characters because a null-terminated string is stored.
Processes aren't named in the object namespace, so the ObjectAttributes is only used for the security descriptor and making the returned handle inheritable. The command line is passed in the ProcessParameters, which is referenced by the Process Environment Block (PEB). With the old NtCreateProcess, these parameters have to be written to the child process via NtWriteVirtualMemory. Nowadays NtCreateUserProcess is used, which combines several calls to a single kernel service -- e.g. creating Section, Process, and Thread objects; and writing the process parameters.
@賈可Jacky, obviously a counted string does not necessarily use a null-terminated string. For example, with the NTAPI registry functions we can create and access key names with nulls in them, but they won't be accessible with WINAPI registry functions, which use null-terminated strings. Likewise, WINAPI CreateProcessW uses a null-terminated string for the command line and application path. The limit is 32,767 - 1, i.e. 32,766 characters.
@eryksun I found that the document about Registry Element Size Limits on MSDN said that the maximum length of a registry key name is 255 characters, but actually you may create a key name of 256 characters. Since the C-style string is just a pointer without length limit, so I guess that it may be possible to pass a string of 32,767 characters to the unicode function CreateProcessW, it may store the exact length in the UNICODE_STRING structure, and set both Length and MaximumLength to 65,534, it is a legal argument for NtCreateProcess.
@賈可Jacky, why guess instead of writing a quick program to test this? It's what I originally did. A command line with 32,767 characters fails with ERROR_FILENAME_EXCED_RANGE (206). This comes from an internal call to RtlInitUnicodeStringEx (NT 5.2+), which requires that the initializing string is a null-terminated string that's no longer than UNICODE_STRING_MAX_CHARS - 1, i.e. 32,766 characters. Older Windows versions called RtlInitUnicodeString, which naively assumes the length is valid and returns nonsense if not, such as Length == 32767 and MaximumLength == 0 (overflow).
|
11

In Windows 10, it's still 8191 characters...at least on my machine.

It just cuts off any text after 8191 characters. Well, actually, I got 8196 characters, and after 8196, then it just won't let me type any more.

Here's a script that will test how long of a statement you can use. Well, assuming you have gawk/awk installed.

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

2 Comments

That's the limit for cmd.exe. As the answer above says, the actual limit is 32,768 characters because of UNICODE_STRING.
I also get the ~8k limit on both Windows 10 and Windows Server 2019 in cmd.exe.