Panjang Maksimum String Baris Perintah

110

Di Windows, berapa panjang maksimum string baris perintah? Artinya jika saya menentukan program yang membutuhkan argumen pada baris perintah sepertiabc.exe -name=abc

Aplikasi konsol sederhana yang saya tulis mengambil parameter melalui baris perintah dan saya ingin tahu berapa jumlah maksimum yang diizinkan.

ST3
sumber
Jika ada yang tertarik, saya sedang mengerjakan cara agar program mendukung baris perintah yang lebih panjang . Dengan asumsi kami dapat membangun dukungan yang cukup untuk itu, ini akan menghapus batasan sepenuhnya tanpa memerlukan Microsoft untuk memperbaiki apa pun, dan dengan cara yang langsung kompatibel. Bukan jawaban untuk pertanyaan itu, tetapi layak memiliki tautan di sini IMO.
alastair

Jawaban:

87

Dari dokumentasi Microsoft: Batasan string baris perintah Command prompt (Cmd. Exe)

Di komputer yang menjalankan Microsoft Windows XP atau yang lebih baru, panjang maksimal string yang dapat Anda gunakan pada prompt perintah adalah 8191 karakter.

sunetos
sumber
33
Ini hanya berlaku untuk program yang benar-benar dijalankan melalui command prompt (sesuai pertanyaan). Pintasan (.lnk) dibatasi hingga 260 karakter, CreateProcess hingga 32767, dan ShellExecute hingga sekitar 2048. Menurut artikel Raymond Chen tentang subjek
NtscCobalt
2 ^ 13-1 karakter, yang menyiratkan ada sesuatu yang dilacak dalam 16 angka dan ini menggunakan 13 bit tersebut. Saya ingin tahu untuk apa 3 bit lainnya?
Sqeaky
@ulrichb Dan sekarang tautan itu juga rusak setelah migrasi blog lagi. Artikel yang dikutip sekarang dapat ditemukan di devblogs.microsoft.com/oldnewthing/20031210-00/?p=41553
Adam Rosenfield
72

Maaf telah menggali utas lama, tetapi saya pikir jawaban sunetos tidak benar (atau bukan jawaban lengkap). Saya telah melakukan beberapa percobaan (menggunakan ProcessStartInfo di c #) dan tampaknya string 'argumen' untuk perintah baris perintah dibatasi hingga 2048 karakter di XP dan 32768 karakter di Win7. Saya tidak yakin apa yang dimaksud dengan batas 8191, tetapi saya belum menemukan buktinya.

Sugrue
sumber
Dari mana Anda mendapatkan angka 32k untuk Win7? Saya tidak dapat menemukan sumber untuk itu. Apakah Anda memikirkan ukuran blok lingkungan ?
Muncul
1
Mungkin. Saya menemukan angka 32k dengan melewatkan argumen yang lebih lama dan lebih lama ke proses melalui kelas C # ProcessStartInfo. Ini membuat pengecualian setelah 32k.
Sugrue
10
@LordTorgamus, Batas 32k karena struktur UNICODE_STRING (panjang ushort). Menurut artikel Raymond Chen tentang CMD subjek membatasi baris menjadi 8192 karakter (saya berasumsi pengembalian carrage adalah karakter terakhir) dan batas ShellExecuteEx menjadi "INTERNET_MAX_URL_LENGTH (sekitar 2048)"
NtscCobalt
1
Bagaimana dengan PowerShell di Windows 10?
Nilzor
1
8191 untuk cmd dan sejenisnya tampak sangat nyata, baru saja menjalankan perintah yang sangat panjang melalui Exec di MSBuild
stijn
41

Sebagai @Sugrue, saya juga menggali utas lama.

Untuk menjelaskan mengapa ada batasan karakter 32.768 (menurut saya seharusnya 32767, tetapi mari percaya hasil pengujian eksperimental), kita perlu menggali ke dalam Windows API.

Tidak peduli bagaimana Anda meluncurkan program dengan argumen baris perintah, ia pergi ke ShellExecute , CreateProcess atau versi diperpanjang mereka. API ini pada dasarnya membungkus API tingkat NT lain yang tidak didokumentasikan secara resmi. Sejauh yang saya tahu panggilan ini membungkus NtCreateProcess , yang membutuhkan struktur OBJECT_ATTRIBUTES sebagai parameter, untuk membuat struktur yang digunakan InitializeObjectAttributes . Di tempat ini kita melihat UNICODE_STRING. Jadi sekarang mari kita lihat struktur ini:

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

Ini menggunakan USHORTvariabel (16-bit length [0; 65535]) untuk menyimpan panjang. Dan menurut ini , panjang menunjukkan ukuran dalam byte, bukan karakter. Jadi kami punya: 65535 / 2 = 32767(karenaWCHAR panjangnya 2 byte).

Ada beberapa langkah untuk menggali angka ini, tapi saya harap ini jelas.


Juga, untuk mendukung @sunetos menjawab apa yang diterima. 8191 adalah jumlah maksimum yang diperbolehkan untuk dimasuki cmd.exe, jika Anda melebihi batas ini, The input line is too long.kesalahan dihasilkan. Jadi, jawaban benar meskipun faktanya itu cmd.exebukan satu-satunya cara untuk menyampaikan argumen untuk proses baru.

ST3
sumber
Panjangnya hingga 32.766 karakter karena string yang diakhiri dengan null disimpan.
Eryk Sun
1
Proses tidak dinamai dalam namespace objek, jadi ObjectAttributeshanya digunakan untuk deskriptor keamanan dan membuat pegangan yang dikembalikan dapat diwariskan. Baris perintah diteruskan di ProcessParameters, yang direferensikan oleh Blok Lingkungan Proses (PEB). Dengan yang lama NtCreateProcess, parameter ini harus ditulis ke proses anak melalui NtWriteVirtualMemory. Saat ini NtCreateUserProcessdigunakan, yang menggabungkan beberapa panggilan ke layanan kernel tunggal - misalnya menciptakan Section, Processdan Threadbenda-benda; dan menulis parameter proses.
Eryk Sun
@eryksun The UNICODE_STRING struktur tidak selalu menyimpan nol terminator.
賈 可 Jacky
@ 賈 可 Jacky, jelas sekali string yang dihitung tidak harus menggunakan string yang diakhiri dengan null. Misalnya, dengan fungsi registri NTAPI, kita dapat membuat dan mengakses nama kunci dengan null di dalamnya, tetapi tidak dapat diakses dengan fungsi registri WINAPI, yang menggunakan string yang diakhiri dengan null. Demikian juga, WINAPI CreateProcessWmenggunakan string diakhiri null untuk baris perintah dan jalur aplikasi. Batasnya adalah 32.767 - 1, yaitu 32.766 karakter.
Eryk Sun
@eryksun Saya menemukan bahwa dokumen tentang Batas Ukuran Elemen Registri di MSDN mengatakan bahwa panjang maksimum nama kunci registri adalah 255 karakter, tetapi sebenarnya Anda dapat membuat nama kunci sebanyak 256 karakter. Karena string C-style hanyalah penunjuk tanpa batas panjang, jadi saya rasa dimungkinkan untuk meneruskan string 32.767 karakter ke fungsi unicode CreateProcessW, itu mungkin menyimpan panjang yang tepat dalam UNICODE_STRINGstruktur, dan mengatur keduanya Lengthdan MaximumLengthmenjadi 65.534 , itu adalah argumen hukum untuk NtCreateProcess.
賈 可 Jacky
3

Di Windows 10, masih ada 8.191 karakter ... setidaknya di komputer saya.

Itu hanya memotong teks apa pun setelah 8191 karakter. Sebenarnya, saya mendapat 8.196 karakter, dan setelah 8196, saya tidak bisa mengetik lagi.

Berikut skrip yang akan menguji berapa lama pernyataan yang dapat Anda gunakan. Nah, dengan asumsi Anda telah menginstal 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
Joseph Dewey
sumber
Itulah batas untuk cmd.exe. Seperti jawaban di atas, batas sebenarnya adalah 32.768 karakter karena UNICODE_STRING.
alastair