命令行字符串的最大长度


110

在Windows中,命令行字符串的最大长度是多少?意思是如果我指定一个程序,该程序在命令行上接受参数,例如abc.exe -name=abc

我编写的一个简单的控制台应用程序通过命令行获取参数,我想知道最大允许量是多少。


如果有人感兴趣,我一直在研究一种程序来支持更长的命令行。假设我们可以为其提供足够的支持,那么这将完全消除这些限制,而无需Microsoft进行任何修复,并且采用了直接兼容的方式。并不是真正的问题答案,但是值得在IMO上找到链接。
alastair

Answers:


87

从Microsoft文档:命令提示符(Cmd.exe)命令行字符串限制

在运行Microsoft Windows XP或更高版本的计算机上,可以在命令提示符下使用的最大字符串长度是8191个字符。


33
这仅适用于实际上通过命令提示符运行的程序(每个问题)。快捷方式(.lnk)限制为260个字符,CreateProcess限制为32767,ShellExecute限制为2048。根据Raymond Chen关于该主题的文章
NtscCobalt

2 ^ 13-1个字符,表示以16个数字跟踪某项,并使用其中的13位。我不知道其他3位是做什么用的?
Sqeaky

@ulrichb现在,在又一次博客迁移之后,该链接也断开了。该引用的文章现在可以在这里找到devblogs.microsoft.com/oldnewthing/20031210-00/?p=41553
亚当罗森菲尔德

72

很抱歉,我想出一个旧的主意,但我认为sunetos的答案不正确(或者不是完整答案)。我做过一些实验(在c#中使用ProcessStartInfo),似乎命令行命令的'arguments'字符串在XP中限制为2048个字符,在Win7中限制为32768个字符。我不确定8191的限制指的是什么,但是我还没有找到任何证据。


您从哪里获得Win7的32k数字?我找不到它的来源。您是否在考虑环境块的大小
2012年

1
可能吧 通过C#ProcessStartInfo类将越来越长的参数传递给进程,我发现了32k的图形。它在32k之后引发异常。
Sugrue 2012年

10
@ LordTorgamus,32k的限制是由于UNICODE_STRING结构(超短长度)引起的。根据雷蒙德·陈(Raymond Chen)关于主题 CMD 的文章,行限制为8192个字符(我认为大括号返回是最后一个字符),而ShellExecuteEx限制为“ INTERNET_MAX_URL_LENGTH(大约2048)”
NtscCobalt 2012年

1
在Windows 10上的PowerShell下如何处理?
Nilzor 2015年

1
8191 for cmd之类的东西看起来非常真实,在MSBuild中通过Exec运行非常长的命令时遇到了这种情况
stijn 18'Aug

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位长度[0; 65535])变量存储长度。并根据,长度表示以字节为单位,而不是以字符大小。所以我们有:(65535 / 2 = 32767因为WCHAR2个字节长)。

有几个步骤可以深入研究这个数字,但是我希望这很清楚。


另外,要支持@sunetos,请回答接受的内容。8191是允许输入的最大数字cmd.exe,如果超出此限制,The input line is too long.则会生成错误。因此,尽管这cmd.exe不是传递新过程参数的唯一方法,但答案是正确的。


长度最多为32,766个字符,因为存储了以null终止的字符串。
Eryk Sun

1
进程未在对象名称空间中命名,因此ObjectAttributes仅用于安全描述符,并使返回的句柄可继承。命令行在ProcessParameters过程环境模块(PEB)引用的中传递。对于旧版本NtCreateProcess,必须通过将这些参数写入子进程NtWriteVirtualMemory。如今NtCreateUserProcess使用,它结合了几个电话,以一个单一的内核服务-例如创建SectionProcessThread对象; 并编写过程参数。
Eryk Sun

@eryksun UNICODE_STRING结构不一定存储空终止符。
贾可Jacky

@贾可Jacky,显然,计数的字符串不一定使用以空值结尾的字符串。例如,使用NTAPI注册表功能,我们可以创建和访问键名称中带有空值的键名,但是使用使用以空字符结尾的字符串的WINAPI注册表功能将无法访问它们。同样,WINAPI CreateProcessW在命令行和应用程序路径中使用以空值结尾的字符串。限制为32,767-1,即32,766个字符。
Eryk Sun

@eryksun我发现有关MSDN上注册表元素大小限制的文档说注册表项名称的最大长度为255个字符,但是实际上您可以创建一个256个字符的项。由于C风格的字符串只是一个没有长度限制的指针,因此我想可能可以将32,767个字符的字符串传递给unicode函数CreateProcessW,它可以在UNICODE_STRING结构中存储确切的长度,并将两者Length和都设置MaximumLength为65,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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.