Длина командной строки в windows

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.

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.

Как @Sugrue я также копаю старую ветку.

Чтобы объяснить, почему существует ограничение в 32768 (я думаю, это должно быть 32767, но давайте поверим в результат экспериментального тестирования) ограничение, которое нам нужно найти в Windows API.

Независимо от того, как вы запускаете программу с аргументами командной строки, она переходит к ShellExecute, CreateProcess или любой расширенной версии. Эти API-интерфейсы в основном обертывают другие API уровня NT, которые официально не документированы. Насколько мне известно, эти вызовы обертывают NtCreateProcess, которому в качестве параметра требуется структура OBJECT_ATTRIBUTES, для создания этой структуры используется InitializeObjectAttributes. В этом месте мы видим UNICODE_STRING, Итак, теперь давайте посмотрим на эту структуру:

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

Оно использует USHORT (16-битная длина [0; 65535]) переменная для хранения длины. И в соответствии с этим длина указывает размер в байтах, а не в символах. Итак, мы имеем: 65535 / 2 = 32767 (так как WCHAR длиной 2 байта).

Есть несколько шагов, чтобы покопаться в этом числе, но я надеюсь, что это понятно.


Также для поддержки @sunetos ответьте, что принято. 8191 — максимально допустимое количество cmd.exeЕсли вы превысите этот предел, The input line is too long. ошибка генерируется. Итак, ответ правильный, несмотря на то, что cmd.exe не единственный способ передать аргументы для нового процесса.

There is a really annoying issue with using command line tools on Windows: the maximum length of the command line passed to cmd.exe is 8192 characters (see http://blogs.msdn.com/b/oldnewthing/archive/2003/12/10/56028.aspx). So you think this is not a problem for you, as you would not pass such a long command line to cmd.exe (the DOS shell under Windows)? Well, if you are using Eclipse (as I do) which generates make files (which is the normal way), then the cmd.exe very likely is involved to call the compiler/linker/etc, indirectly with the usage of make.exe. Compiling files is usually not a problem as it does not hit that 8192 limit. However, it is likely that link phase will end up with an error:

Error in the Problems View

Error in the Problems View

If you have such a problem, there is a solution ….

Failure to Link?

Looking at the Console output, it is clearly the link phase which failed:

Linker failed because of 8192 character limit

Linker failed because of 8192 character limit

So what happened? I’m using source files with a rather long directory path, and many of them (e.g. building the CMSIS library, see “Tutorial: Using the ARM CMSIS Library“). Because that library/project has many, many files which need to be linked, it will fail at the link phase. In my above test example I have a command line length passed to the linker which is 12316 characters long!

The error might be a strange one, maybe saying something like it cannot find or execute an object file. Because the command line gets cut somewhere, the error message reported usually does not give a clear clue.

The problem is not the problem of Eclipse: it is rather the problem of make how much it accepts on the command line and long the command line to the gcc compiler and linker can be. The problem can be easly reproduce with my DIY toolchain and is present in other vendor toolchains like the Freescale Kinetis Design Studio (tried with v2.0.0) on Windows.

💡 CodeWarrior for MCU solves that problem with a custom build tools integration: instead of passing the full set of arguments on the command line, it uses files with the options/commands in it. So it passes the options to the called process with pointing to a file. Unfortunately this is not present in the widely used GNU ARM Eclipse plugins (see support request #25 and support request #32).

Oh yeah, I hear now already the voices singing: “Dude, it’s your fault, why are you using Windows? Use Linux!” because this problem does not exist on Linux. Oh well, do not get me there 😉

The obvious solution is to keep the command line as short as possible, especially for the linker:

  1. Use short directory names
  2. Use short file names
  3. Reduce the command line length with using relative paths instead of absolute file paths
  4. If this does not help: build part of the application as a library and then link the library with the final application

Needless to say that this is all very time consuming and just a workaround for the problem. The solution is to use the GNU ARM Eclipse Build Tools package instead.

GNU ARM Eclipse Build Tools

Luckily, there is now a solution available for Windows, thanks to the Liviu and the GNU ARM Eclipse work :-). The solution is available from the version v2.6.1 or later of the GNU ARM Eclipse Plugins build tools, and the release notes reads:

“The new Build Tools v2.3 include a better shell version, instead of the Windows cmd.exe, so the annoying 8K limit on command line lengths was removed.”

Oh, wow! So this is the solution is to use these build tools, and then that 8192 character command line limit should be gone? Yes, it is :-)!

Installing the Solution

The latest build (v2.4 at the time of this writing) is available from https://sourceforge.net/projects/gnuarmeclipse/files/Build%20Tools/.

GNU ARM Eclipse Build Tools

GNU ARM Eclipse Build Tools

Download the setup executable and run it.

GNU ARM Eclipse Build Tools Installer

GNU ARM Eclipse Build Tools Installer

On my machine, the build tools get installed into

C:\Program Files (x86)\GNU ARM Eclipse\Build Tools\2.4-201503242026\bin

GNU ARM Eclipse Build Tools Installed

GNU ARM Eclipse Build Tools Installed

Now make sure that these tools are used instead of the ones with the 8192 command line character limit. For Kinetis Design Studio v2.0.0, the build tools are located in these sub folders:

  1. make.exe is in <kds_2.0.0>\toolchain\bin
  2. echo.exe and rm.exe are in <kds_2.0.0>\bin

Rename the existing make.exe, rm.exe and echo.exe so you have a backup. Then copy the files from the GNU ARM Eclipse build tools into the KDS bin folder:

GNU ARM Eclipse Build Tools in KDS

GNU ARM Eclipse Build Tools in KDS

Because I have renamed the existing make.exe, rm.exe and echo.exe, they are not found any more and the new versions are used instead with the sh.exe which fixes that annoying Windows problem. And if I do a build now with my long command line, it does works :-):

Success building with GNU and very long command line

Success building with GNU and very long command line

Summary

Windows (better, cmd.exe) has a command line length limit of 8192 characters. The GNU ARM Eclipse build tools provided by Liviu have fixed this with a new sh.exe. Using the GNU ARM Eclipse build tools allowed me overcome that Windows limit. The fix is easy to apply: replace the limited cmd.exe based tools with teh GNU ARM Eclipse ones which use the sh.exe.

Happy Shelling 🙂

PS: Liviu, you probably read this, and I know you are using Mac OS, and you are not a fan of Windows environment for good reasons. On behalf of the Windows user community: THANK YOU, THANK YOU, THANK YOU!

Это перевод What is the command line length limit? Автор: Реймонд Чен.

Зависит от того, о чём вы спрашиваете.

Максимальная длина строки для функции CreateProcess — это 32767 символов. Это ограничение идёт из записи UNICODE_STRING (TUnicodeString в JwaWinTypes.pas).

CreateProcess — это функция ядра для создания процессов, поэтому, если вы общаетесь напрямую с Win32, то это будет единственным ограничением, о котором вам нужно волноваться. Но если вы работаете с CreateProcess ещё через кого-то, то по пути доступа могут стоять и другие ограничения.

Если вы используете коммандный процессор CMD.EXE, тогда вы сталкиваетесь с пределом в 8192 символов — это ограничение командной строки, вносимое самим CMD.EXE.

Если вы используете функции ShellExecute/Ex, тогда вы будете ограничены INTERNET_MAX_URL_LENGTH (около 2048) символами на командную строку, вводимыми функциями ShellExecute/Ex (а если вы работаете в Windows 95, то тогда предел и вовсе MAX_PATH символов).

Пока я обсуждаю этот вопрос, я хотел бы упомянуть и другое ограничение: максимальный размер ваших переменных окружения — это 32767 символов. Размер переменных окружения включает в себя все имена переменных плюс их значения.

Окей, но что если вам нужно передать процессу больше, чем 32767 символов данных? Тогда вам придётся поискать другие пути, отличные от командной строки.

Читать далее.

  • Длина имени папки в windows
  • Для windows 10 отключить фильтр smartscreen
  • Дистрибутив операционной системы windows 10
  • Дисплей 2 неактивен windows 10
  • Для windows 10 нужен mbr или gpt