134

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.

ST3
  • 8,826
  • 3
  • 68
  • 92
  • If anyone is interested, I've been working on [a way for programs to support longer command lines](https://github.com/al45tair/ArgX). Assuming we can build enough support for it, this would remove the restrictions completely without requiring Microsoft to fix anything, and in a manner that is straightforwardly compatible. Not really an answer to the question, but worth having a link here IMO. – al45tair Jan 12 '20 at 09:11

4 Answers4

104

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.

Mofi
  • 46,139
  • 17
  • 80
  • 143
sunetos
  • 3,448
  • 1
  • 23
  • 14
  • 46
    This only applies to the programs actually run through the command prompt (per the question). Shortcuts (.lnk) are limited to 260 characters, CreateProcess to 32767, and ShellExecute to about 2048. [According to Raymond Chen's article on the subject](http://blogs.msdn.com/b/oldnewthing/archive/2003/12/10/56028.aspx) – NtscCobalt Oct 24 '12 at 21:47
  • 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? – Sqeaky Jan 25 '16 at 22:45
  • 4
    @ulrichb And now that link is broken too after yet another blog migration. The cited article can now be found at https://devblogs.microsoft.com/oldnewthing/20031210-00/?p=41553 – Adam Rosenfield May 06 '20 at 05:09
  • 1
    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. – Lothar Jan 01 '22 at 23:44
76

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.

Community
  • 1
  • 1
Sugrue
  • 3,629
  • 5
  • 35
  • 53
  • 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](http://blogs.msdn.com/b/oldnewthing/archive/2010/02/03/9957320.aspx)? – Pops Oct 03 '12 at 19:25
  • 1
    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. – Sugrue Oct 04 '12 at 09:11
  • 14
    @LordTorgamus, The 32k limit is due to the [UNICODE_STRING](http://msdn.microsoft.com/en-us/library/windows/desktop/aa380518%28v=vs.85%29.aspx) structure (ushort length). [According to Raymond Chen's article on the subject](http://blogs.msdn.com/b/oldnewthing/archive/2003/12/10/56028.aspx) 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)" – NtscCobalt Oct 24 '12 at 21:32
  • Definitely more like a 32k limit for me on Windows 7 – davidfrancis Nov 21 '12 at 10:45
  • 5
    What about under PowerShell on Windows 10? – Nilzor Dec 09 '15 at 09:34
  • 2
    8191 for cmd and the likes seems very real, just ran into this when running a very long command via Exec in MSBuild – stijn Aug 24 '18 at 13:50
  • Big evidence for a 8191 limit: paste any command into a DOS prompt under Windows 10 x64, and it truncates it to 8191 characters. Your answer is incorrect enough to be misleading. – Contango Oct 11 '20 at 08:56
  • @Contango have you tried WinTerminal instead of cmd.exe. I hope it can't be still that limited. – Lothar Jan 01 '22 at 23:46
52

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.

ST3
  • 8,826
  • 3
  • 68
  • 92
  • 4
    The length is up to 32,766 characters because a null-terminated string is stored. – Eryk Sun Jun 14 '17 at 13:36
  • 1
    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. – Eryk Sun Jun 14 '17 at 13:41
  • @eryksun The **UNICODE_STRING** structure does not necessarily store null terminator. – xenophōn Jun 03 '19 at 02:31
  • 1
    @賈可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. – Eryk Sun Jun 03 '19 at 05:37
  • @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`. – xenophōn Jun 03 '19 at 09:34
  • @賈可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). – Eryk Sun Jun 03 '19 at 12:25
  • @eryksun Thanks! I have never tested it. – xenophōn Jun 03 '19 at 13:25
  • Are these numbers including path to the executable, or only applied the command line arguments? – vanowm Jun 16 '20 at 21:27
9

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
Joseph Dewey
  • 91
  • 1
  • 2