명령 줄 문자열의 최대 길이


110

Windows에서 명령 줄 문자열의 최대 길이는 얼마입니까? 명령 줄에서 다음과 같은 인수를받는 프로그램을 지정하면abc.exe -name=abc

내가 작성한 간단한 콘솔 애플리케이션은 명령 줄을 통해 매개 변수를 가져 오며 최대 허용량을 알고 싶습니다.


관심이 있으시면 프로그램이 더 긴 명령 줄을 지원하는 방법을 연구하고 있습니다 . 이에 대한 충분한 지원을 구축 할 수 있다고 가정하면 Microsoft가 어떤 것도 수정하지 않고도 간단하게 호환되는 방식으로 제한 사항을 완전히 제거 할 수 있습니다. 질문에 대한 답은 아니지만 여기에 링크가있는 가치가 있습니다. IMO.
alastair

답변:


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
Adam Rosenfield

72

오래된 스레드를 파헤쳐 서 죄송하지만 sunetos의 답변 이 정확하지 않거나 전체 답변이 아닌 것 같습니다. 몇 가지 실험 (C #에서 ProcessStartInfo 사용)을 수행했으며 명령 줄 명령의 '인수'문자열이 XP에서는 2048 자, Win7에서는 32768 자로 제한되는 것 같습니다. 8191 제한이 무엇을 의미하는지 잘 모르겠지만 아직 증거를 찾지 못했습니다.


Win7의 32k 수치는 어디서 구했습니까? 그 출처를 찾을 수 없습니다. 환경 블록의 크기 를 생각하고 있습니까?
Pops

1
혹시. C # ProcessStartInfo 클래스를 통해 더 길고 더 긴 인수를 프로세스에 전달하여 32k 그림을 찾았습니다. 32k 후에 예외가 발생합니다.
Sugrue

10
@LordTorgamus, 32k 제한은 UNICODE_STRING 구조 (ushort 길이) 때문입니다. 주제에 대한 Raymond Chen의 기사에 따르면 CMD는 행을 8192 자로 제한하고 (carrage return은 최종 문자라고 가정합니다) ShellExecuteEx는 "INTERNET_MAX_URL_LENGTH (약 2048)"로 제한합니다.
NtscCobalt 2012 년

1
Windows 10의 PowerShell에서는 어떻습니까?
Nilzor 2015

1
cmd에 대한 8191 및 좋아하는
것들은

41

@Sugrue로서 나는 또한 오래된 스레드를 파헤 치고 있습니다.

32768 (32767이어야한다고 생각하지만 실험적인 테스트 결과를 믿도록하겠습니다) 문자 제한이있는 이유를 설명하려면 Windows API를 파헤쳐 야합니다.

명령 줄 인수로 프로그램을 시작하는 방법에 관계없이 ShellExecute , CreateProcess 또는 확장 된 버전으로 이동합니다. 이러한 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( WCHAR길이가 2 바이트 이기 때문에 ).

이 숫자를 파헤치는 몇 가지 단계가 있지만 명확하기를 바랍니다.


또한 @sunetos를 지원하려면 허용되는 내용에 응답하십시오. 8191은에 입력 할 수있는 최대 수이며이 cmd.exe제한을 초과하면 The input line is too long.오류가 생성됩니다. 따라서 cmd.exe새로운 프로세스에 대한 인수를 전달하는 유일한 방법은 아니지만 대답은 정확 합니다.


널로 끝나는 문자열이 저장되므로 길이는 최대 32,766 자입니다.
Eryk Sun

1
프로세스는 개체 네임 스페이스에서 이름이 지정되지 않으므로 ObjectAttributes보안 설명자에만 사용되며 반환 된 핸들을 상속 가능하게 만듭니다. 명령 줄은 ProcessParametersPEB (Process Environment Block)에서 참조하는 에서 전달됩니다 . 이전의 NtCreateProcess경우 이러한 매개 변수는를 통해 자식 프로세스에 기록되어야합니다 NtWriteVirtualMemory. 요즘에는 NtCreateUserProcess하나의 커널 서비스에 대한 여러 호출을 결합하는 방식이 사용됩니다 (예 : ,, 객체 생성 Section) . 및 프로세스 매개 변수 작성. ProcessThread
Eryk Sun

@eryksun UNICODE_STRING 구조는 반드시 null 종결 자를 저장하지 않습니다.
賈 可 Jacky

@ 賈 可 Jacky, 분명히 계산 된 문자열이 반드시 null로 끝나는 문자열을 사용하는 것은 아닙니다. 예를 들어 NTAPI 레지스트리 함수를 사용하면 null이 포함 된 키 이름을 만들고 액세스 할 수 있지만 null로 끝나는 문자열을 사용하는 WINAPI 레지스트리 함수로는 액세스 할 수 없습니다. 마찬가지로 WINAPI CreateProcessW는 명령 줄과 응용 프로그램 경로에 대해 null로 끝나는 문자열을 사용합니다. 제한은 32,767-1, 즉 32,766 자입니다.
Eryk Sun

@eryksun MSDN의 레지스트리 요소 크기 제한 에 대한 문서 에서 레지스트리 키 이름의 최대 길이가 255 자라고 나와 있지만 실제로는 256 자의 키 이름을 만들 수 있습니다. 나는 유니 코드 기능에 32,767 문자열을 통과 할 수있을 수 있다는 생각 때문에 C 스타일의 문자열 길이 제한이없는 단지 포인터이기 때문에 CreateProcessW, 그것은 정확한 길이 저장할 수 UNICODE_STRING구조와 세트 모두 LengthMaximumLength65,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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.