Lunghezza massima della stringa della riga di comando


110

In Windows, qual è la lunghezza massima di una stringa della riga di comando? Significa che se specifico un programma che accetta argomenti sulla riga di comando comeabc.exe -name=abc

Una semplice applicazione console che ho scritto prende i parametri tramite la riga di comando e voglio sapere qual è la quantità massima consentita.


Se qualcuno è interessato, sto lavorando a un modo in cui i programmi supportino righe di comando più lunghe . Supponendo di poter creare un supporto sufficiente per esso, ciò rimuoverebbe completamente le restrizioni senza richiedere a Microsoft di riparare nulla e in un modo che sia direttamente compatibile. Non proprio una risposta alla domanda, ma vale la pena avere un link qui IMO.
alastair

Risposte:


87

Dalla documentazione Microsoft: Limitazione della stringa della riga di comando del prompt dei comandi (Cmd. Exe)

Nei computer che eseguono Microsoft Windows XP o versioni successive, la lunghezza massima della stringa che è possibile utilizzare al prompt dei comandi è di 8191 caratteri.


33
Questo si applica solo ai programmi effettivamente eseguiti tramite il prompt dei comandi (secondo la domanda). Le scorciatoie (.lnk) sono limitate a 260 caratteri, CreateProcess a 32767 e ShellExecute a circa 2048. Secondo l'articolo di Raymond Chen sull'argomento
NtscCobalt

2 ^ 13-1 caratteri, ciò implica che qualcosa è tracciato in un numero 16 e questo utilizza 13 di quei bit. Mi chiedo a cosa servono gli altri 3 bit?
Sqeaky

@ulrichb E ora anche quel collegamento è interrotto dopo l'ennesima migrazione del blog. L'articolo citato può ora essere trovato su devblogs.microsoft.com/oldnewthing/20031210-00/?p=41553
Adam Rosenfield

72

Ci scusiamo per aver scavato un vecchio thread, ma penso che la risposta di sunetos non sia corretta (o non sia la risposta completa). Ho fatto alcuni esperimenti (usando ProcessStartInfo in c #) e sembra che la stringa "argomenti" per un comando da riga di comando sia limitata a 2048 caratteri in XP e 32768 caratteri in Win7. Non sono sicuro a cosa si riferisca il limite 8191, ma non ne ho ancora trovato alcuna prova.


Dove hai preso la cifra di 32k per Win7? Non riesco a trovare una fonte per questo. Stai pensando alle dimensioni del blocco ambientale ?
Pop il

1
Possibilmente. Ho trovato la cifra 32k passando argomenti sempre più lunghi a un processo tramite la classe ProcessStartInfo C #. Genera un'eccezione dopo 32k.
Sugrue

10
@LordTorgamus, Il limite 32k è dovuto alla UNICODE_STRING struttura (lunghezza USHORT). Secondo l'articolo di Raymond Chen sull'argomento, CMD limita le righe a 8192 caratteri (presumo che il ritorno del carrello sia il carattere finale) e ShellExecuteEx limita a "INTERNET_MAX_URL_LENGTH (intorno al 2048)"
NtscCobalt

1
E sotto PowerShell su Windows 10?
Nilzor

1
8191 per cmd e simili sembra molto reale, mi sono imbattuto in questo quando si esegue un comando molto lungo tramite Exec in MSBuild
stijn

41

Come @Sugrue sto anche scavando un vecchio thread.

Per spiegare perché c'è 32768 (penso che dovrebbe essere 32767, ma crediamo che il risultato del test sperimentale) limiti di caratteri dobbiamo scavare nell'API di Windows.

Non importa come si avvia il programma con gli argomenti della riga di comando, va a ShellExecute , CreateProcess o qualsiasi altra versione estesa. Queste API fondamentalmente racchiudono altre API di livello NT che non sono ufficialmente documentate. Per quanto ne so queste chiamate avvolgono NtCreateProcess , che richiede la struttura OBJECT_ATTRIBUTES come parametro, per creare quella struttura viene utilizzata InitializeObjectAttributes . In questo posto vediamo UNICODE_STRING. Quindi ora diamo un'occhiata a questa struttura:

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

Utilizza la USHORTvariabile (lunghezza a 16 bit [0; 65535]) per memorizzare la lunghezza. E secondo questo , la lunghezza indica la dimensione in byte, non in caratteri. Quindi abbiamo: 65535 / 2 = 32767(perché WCHARè lungo 2 byte).

Ci sono alcuni passaggi per approfondire questo numero, ma spero che sia chiaro.


Inoltre, per supportare @sunetos rispondi a ciò che è accettato. 8191 è un numero massimo consentito di essere inserito cmd.exe, se si supera questo limite, The input line is too long.viene generato un errore. Quindi, la risposta è corretta nonostante il fatto che cmd.exenon sia l'unico modo per passare argomenti per un nuovo processo.


La lunghezza è fino a 32.766 caratteri perché viene archiviata una stringa con terminazione null.
Eryk Sun

1
I processi non sono denominati nello spazio dei nomi dell'oggetto, quindi ObjectAttributesviene utilizzato solo per il descrittore di sicurezza e per rendere ereditabile l'handle restituito. La riga di comando viene passata in ProcessParameters, a cui fa riferimento il Process Environment Block (PEB). Con il vecchio NtCreateProcess, questi parametri devono essere scritti nel processo figlio tramite NtWriteVirtualMemory. Al giorno d'oggi NtCreateUserProcessè usato, che combina diverse chiamate a un singolo servizio di kernel - ad esempio, la creazione Section, Processe Threadgli oggetti; e scrivere i parametri di processo.
Eryk Sun

@eryksun La struttura UNICODE_STRING non memorizza necessariamente il terminatore nullo.
賈 可 Jacky

@ 賈 可 Jacky, ovviamente una stringa conteggiata non usa necessariamente una stringa con terminazione null. Ad esempio, con le funzioni di registro NTAPI possiamo creare e accedere a nomi di chiavi contenenti valori nulli, ma non saranno accessibili con le funzioni di registro WINAPI, che utilizzano stringhe con terminazione null. Allo stesso modo, WINAPI CreateProcessWutilizza una stringa con terminazione null per la riga di comando e il percorso dell'applicazione. Il limite è 32.767 - 1, ovvero 32.766 caratteri.
Eryk Sun

@eryksun Ho scoperto che il documento sui limiti di dimensione degli elementi del registro su MSDN dice che la lunghezza massima del nome di una chiave di registro è di 255 caratteri, ma in realtà è possibile creare un nome di chiave di 256 caratteri. Poiché la stringa in stile C è solo un puntatore senza limite di lunghezza, quindi immagino che potrebbe essere possibile passare una stringa di 32.767 caratteri alla funzione unicode CreateProcessW, potrebbe memorizzare la lunghezza esatta nella UNICODE_STRINGstruttura e impostare sia Lengthe MaximumLength65.534 , è un argomento legale per NtCreateProcess.
賈 可 Jacky

3

In Windows 10, sono ancora 8191 caratteri ... almeno sulla mia macchina.

Taglia solo il testo dopo 8191 caratteri. Bene, in realtà, ho 8196 caratteri e dopo 8196 non mi permette più di digitare.

Ecco uno script che metterà alla prova la durata di un'istruzione che puoi utilizzare. Bene, supponendo che tu abbia installato 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

Questo è il limite per cmd.exe. Come dice la risposta sopra, il limite effettivo è di 32.768 caratteri a causa di UNICODE_STRING.
alastair
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.