What is the command line length limit?

Date:December 10, 2003 / year-entry #157
Tags:code
Orig Link:https://blogs.msdn.microsoft.com/oldnewthing/20031210-00/?p=41553
Comments:    16
Summary:It depends on whom you ask. The maximum command line length for the CreateProcess function is 32767 characters. This limitation comes from the UNICODE_STRING structure. CreateProcess is the core function for creating processes, so if you are talking directly to Win32, then that's the only limit you have to worry about. But if you are...

It depends on whom you ask.

The maximum command line length for the CreateProcess function is 32767 characters. This limitation comes from the UNICODE_STRING structure.

CreateProcess is the core function for creating processes, so if you are talking directly to Win32, then that's the only limit you have to worry about. But if you are reaching CreateProcess by some other means, then the path you travel through may have other limits.

If you are using the CMD.EXE command processor, then you are also subject to the 8192 character command line length limit imposed by CMD.EXE.

If you are using the ShellExecute/Ex function, then you become subject to the INTERNET_MAX_URL_LENGTH (around 2048) command line length limit imposed by the ShellExecute/Ex functions. (If you are running on Windows 95, then the limit is only MAX_PATH.)

While I'm here, I may as well mention another limit: The maximum size of your environment is 32767 characters. The size of the environment includes the all the variable names plus all the values.

Okay, but what if you want to pass more than 32767 characters of information to a process? You'll have to find something other than the command line. We'll discuss some options tomorrow.


Comments (16)
  1. Juan Miguel Venturello says:

    Thanks for this blog Raymond, this is very interesting. Looking forward to the answers tomorrow, I can imagine what some of them will be ;)
    This weekend I went through all your blog archives and learnt many, many things I have always wondered about in my win32 developer career, and a few new tricks.

    As many said, this is book material :) Good luck with all and again, thanks,

    Juan Miguel Venturello

  2. Jordan Russell says:

    I never knew ShellExecute imposed such a limitation. Very good to know.

    Here’s an unrelated question that might make for an interesting blog topic:

    Why does FILE_ATTRIBUTE_NORMAL exist, and why is it defined as 0x00000080? Why not just use 0 when no special attributes are set?

  3. Catatonic says:

    What is the limit for _spawnv(), where you supply your own argv to the process? I use this in my code because I don’t have to worry about quoting or escaping special characters.

  4. Catatonic says:

    Whoops, forgot to post the answer! The limit for _spawnv is a measly 1024 bytes.

  5. Anonymous says:

    _spawnv eventually calls CreateProcess but there doesn’t seem to be any limit checks before it calls it (at least in the CRT for VS6).

  6. Anonymous says:

    The CRT for VS6 doesn’t check for that limit at all. Infact, it doesn’t even use arg_len in _cenvarg at all.

  7. Raymond Chen says:

    For historical completeness: The DOS command line length limit was 127 characters.

  8. Catatonic says:

    Interesting. The MSDN documentation for _spawnv must say 1024 bytes for a reason. Just to be safe I’d better stick to it!

  9. Mike Dunn says:

    To pass > 32K chars, use a memory mapped file. You can pass the name of the MMF object (or a handle value, if you let the 2nd app inherit handles from the first) and the length of the memory block on the command line:

    Pass 261004 bytes in the MMF called "MyMMFThingy"

    appnumber2.exe /n "MyMMFThingy" /l 261004

    Then of course you add some sync code so that the MMF stays around for as long as both apps need it to.

  10. Raymond Chen says:

    Mike got it basically right. Except that you don’t want to pass the length on the command line; somebody could pass a bogus length and cause you to crash. And coming up with a unique name can be tricky (plus giving it a name opens you up to attackers who can grab the shared memory object file and look at or even mess with it before the child looks at it — this is a data tampering / information disclosure attack; you can prevent this by applying ACLs to your shared memory object). I prefer an anonymous inheritable handle, which avoids the synchronization problem as well.

  11. Mike Dunn says:

    Both good points, Raymond. This teaches me that I shouldn’t write code with security implications at 12:25 AM ;)

  12. James Curran says:

    Raymond,
    I love the Code/History notes. Do you take requests?

    One of the bugaboos of Undocumented MSDOS coding was attempting to change the master environment variables block. (If I recall correctly, by DOS6, there were six different ways to find it — none of which were guaranteed to work, so you had to try all six, and use the number which came up the most).
    Which bring us to the question — Why did microsoft never provide a nice simple (say, INT 21h) interface to add & remove evars.

  13. Raymond Chen says:

    Because you aren’t supposed to change the environment of another process, much less the root environment block. Unix doesn’t let you do it either.

  14. Paraesthesia says:

    Dynamic FxCop Dependency List Using MSBuild

Comments are closed.


*DISCLAIMER: I DO NOT OWN THIS CONTENT. If you are the owner and would like it removed, please contact me. The content herein is an archived reproduction of entries from Raymond Chen's "Old New Thing" Blog (most recent link is here). It may have slight formatting modifications for consistency and to improve readability.

WHY DID I DUPLICATE THIS CONTENT HERE? Let me first say this site has never had anything to sell and has never shown ads of any kind. I have nothing monetarily to gain by duplicating content here. Because I had made my own local copy of this content throughout the years, for ease of using tools like grep, I decided to put it online after I discovered some of the original content previously and publicly available, had disappeared approximately early to mid 2019. At the same time, I present the content in an easily accessible theme-agnostic way.

The information provided by Raymond's blog is, for all practical purposes, more authoritative on Windows Development than Microsoft's own MSDN documentation and should be considered supplemental reading to that documentation. The wealth of missing details provided by this blog that Microsoft could not or did not document about Windows over the years is vital enough, many would agree an online "backup" of these details is a necessary endeavor. Specifics include:

<-- Back to Old New Thing Archive Index