कमांड लाइन स्ट्रिंग की अधिकतम लंबाई


110

विंडोज में, कमांड लाइन स्ट्रिंग की अधिकतम लंबाई क्या है? मतलब अगर मैं एक प्रोग्राम निर्दिष्ट करता हूं जो कमांड लाइन पर तर्क देता है जैसे किabc.exe -name=abc

एक साधारण कंसोल एप्लिकेशन जो मैंने लिखा था, कमांड लाइन के माध्यम से पैरामीटर लेता है और मैं जानना चाहता हूं कि अधिकतम स्वीकार्य राशि क्या है।


अगर किसी को दिलचस्पी है, तो मैं प्रोग्राम्स के लिए लंबे समय तक कमांड लाइनों का समर्थन करने के तरीके पर काम कर रहा हूं । यह मानते हुए कि हम इसके लिए पर्याप्त समर्थन का निर्माण कर सकते हैं, यह Microsoft को कुछ भी ठीक करने की आवश्यकता के बिना प्रतिबंधों को पूरी तरह से हटा देगा, और एक तरह से जो सीधे संगत है। वास्तव में सवाल का जवाब नहीं है, लेकिन यहाँ एक लिंक होने के लायक है IMO।
एलेस्टेयर

जवाबों:


87

Microsoft दस्तावेज़ीकरण से: कमांड प्रॉम्प्ट (Cmd। Exe) कमांड-लाइन स्ट्रिंग लिमिटेशन

Microsoft Windows XP या बाद में चलने वाले कंप्यूटर पर, स्ट्रिंग की अधिकतम लंबाई जिसे आप कमांड प्रॉम्प्ट पर उपयोग कर सकते हैं, 8191 वर्ण है।


33
यह केवल कमांड प्रॉम्प्ट (प्रश्न के अनुसार) के माध्यम से चलने वाले कार्यक्रमों पर लागू होता है। शॉर्टकट (.lnk) 260 वर्णों तक, CreateProcess से 32767 तक और ShellExecute से लगभग 2048 तक सीमित हैं। इस विषय पर रेमंड चेन के लेख के अनुसार
NtscCobalt

2 ^ 13-1 वर्ण, जिसका तात्पर्य है कि किसी चीज़ को 16 नंबर में ट्रैक किया जाता है और इसमें से 13 बिट्स का उपयोग किया जाता है। मुझे आश्चर्य है कि अन्य 3 बिट्स किस लिए हैं?
सकी

@ulrichb और अब वह लिंक एक और ब्लॉग माइग्रेशन के बाद भी टूट गया है। उद्धृत लेख अब devblogs.microsoft.com/oldnewthing/20031210-00/?p=41553
एडम रोसेनफील्ड

72

एक पुराना धागा खोदने के लिए क्षमा करें, लेकिन मुझे लगता है कि sunetos का उत्तर सही नहीं है (या पूर्ण उत्तर नहीं है)। मैंने कुछ प्रयोग किए हैं (सी में #StatStartInfo का उपयोग करके) और ऐसा लगता है कि एक कमांडलाइन कमांड के लिए 'तर्क' स्ट्रिंग XP में 2048 वर्णों और Win7 में 32768 वर्णों तक सीमित है। मुझे यकीन नहीं है कि 8191 सीमा का क्या मतलब है, लेकिन मुझे अभी तक इसका कोई सबूत नहीं मिला है।


Win7 के लिए आपको 32k आंकड़ा कहां मिलेगा? मैं उस के लिए एक स्रोत नहीं मिल सकता है। क्या आप पर्यावरण ब्लॉक के आकार के बारे में सोच रहे हैं ?
पोप

1
संभवतः। मैंने C # ProcessStartInfo वर्ग के माध्यम से एक प्रक्रिया में लंबी और लंबी बहस पास करके 32k आंकड़ा पाया। यह 32k के बाद एक अपवाद फेंकता है।
सूक्रू

10
@LordTorgamus, 32k की सीमा UNICODE_STRING संरचना (ushort लंबाई) के कारण है। सीएमडी विषय पर रेमंड चेन के लेख के अनुसार 8192 वर्णों के लिए सीएमडी की सीमाएँ हैं (मैं मानूंगा कि कैरिज रिटर्न अंतिम चरित्र है) और
शेलएक्सक्यूटेक्स

1
विंडोज 10 पर पावरशेल के तहत क्या है?
निलज़ोर

1
Cmd के लिए 8191 और पसंद बहुत वास्तविक लगती है, बस MSBuild में Exec के माध्यम से एक बहुत लंबी कमांड चलाते समय इसमें भाग गया
stijn

41

@Sugrue के रूप में मैं एक पुराना धागा भी खोद रहा हूं।

यह समझाने के लिए कि 32768 क्यों है (मुझे लगता है कि यह 32767 होना चाहिए, लेकिन प्रायोगिक परीक्षण परिणाम पर विश्वास करने देता है) वर्ण सीमाएं जिसे हमें विंडोज एपीआई में खोदने की आवश्यकता है।

कोई भी बात नहीं है कि आप कमांड लाइन के तर्कों के साथ प्रोग्राम कैसे लॉन्च करते हैं, यह 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(क्योंकि WCHAR2 बाइट्स लंबी हैं)।

इस संख्या में खुदाई करने के लिए कुछ कदम हैं, लेकिन मुझे उम्मीद है कि यह स्पष्ट है।


इसके अलावा, @sunetos का समर्थन करने के लिए जो स्वीकार किया जाता है। 8191 एक अधिकतम संख्या है जिसे प्रवेश करने की अनुमति है cmd.exe, यदि आप इस सीमा से अधिक हो जाते हैं, तो The input line is too long.त्रुटि उत्पन्न होती है। इसलिए, उत्तर इस तथ्य के बावजूद सही है कि cmd.exeनई प्रक्रिया के लिए तर्क पारित करने का एकमात्र तरीका नहीं है।


लंबाई 32,766 वर्णों तक है क्योंकि एक नल-समाप्त स्ट्रिंग संग्रहीत है।
इरीक सन

1
ऑब्जेक्ट नामस्थान में प्रक्रियाओं का नाम नहीं दिया गया है, इसलिए इसका ObjectAttributesउपयोग केवल सुरक्षा डिस्क्रिप्टर और रिटर्न हैंडल को इनहेरिटेबल बनाने के लिए किया जाता है। कमांड लाइन में पारित किया जाता है ProcessParameters, जिसे प्रक्रिया पर्यावरण ब्लॉक (पीईबी) द्वारा संदर्भित किया जाता है। पुराने के साथ NtCreateProcess, इन मापदंडों को बाल प्रक्रिया के माध्यम से लिखना होगा NtWriteVirtualMemory। आजकल NtCreateUserProcessप्रयोग किया जाता है, जो एक एकल कर्नेल सेवा करने के लिए कई कॉल को जोड़ती है - जैसे निर्माण Section, Processऔर Threadवस्तुओं; और प्रक्रिया के मापदंडों को लिखना।
इरीक सन

@eryksun UNICODE_STRING संरचना आवश्यक रूप से शून्य टर्मिनेटर को संग्रहीत नहीं करती है।
賈 जैकी

@ @ 賈 जैकी, स्पष्ट रूप से एक गणना स्ट्रिंग एक शून्य-समाप्त स्ट्रिंग का उपयोग नहीं करता है। उदाहरण के लिए, NTAPI रजिस्ट्री फ़ंक्शंस के साथ हम उन में नल के साथ मुख्य नाम बना सकते हैं और एक्सेस कर सकते हैं, लेकिन वे WinAPI रजिस्ट्री फ़ंक्शंस के साथ सुलभ नहीं होंगे, जो कि शून्य-टर्मिनेटेड स्ट्रिंग्स का उपयोग करते हैं। इसी तरह, WinAPI CreateProcessWकमांड लाइन और एप्लिकेशन पथ के लिए एक शून्य-समाप्त स्ट्रिंग का उपयोग करता है। सीमा 32,767 - 1, यानी 32,766 अक्षर है।
इरीक सन

@eryksun मैंने पाया कि MSDN पर रजिस्ट्री एलिमेंट साइज़ लिमिट के बारे में दस्तावेज़ ने कहा कि रजिस्ट्री कुंजी नाम की अधिकतम लंबाई 255 वर्ण है, लेकिन वास्तव में आप 256 वर्णों का एक प्रमुख नाम बना सकते हैं। चूंकि सी-स्टाइल स्ट्रिंग केवल लंबाई की सीमा के बिना एक संकेतक है, इसलिए मुझे लगता है कि यूनिकोड फ़ंक्शन में 32,767 वर्णों की एक स्ट्रिंग को पारित करना संभव हो सकता है CreateProcessW, यह UNICODE_STRINGसंरचना में सटीक लंबाई स्टोर कर सकता है , और दोनों को Lengthऔर MaximumLength65,534 पर सेट कर सकता है , यह एक कानूनी तर्क है NtCreateProcess
9 賈 जैकी

3

विंडोज 10 में, यह अभी भी 8191 अक्षर है ... कम से कम मेरी मशीन पर।

यह सिर्फ 8191 अक्षरों के बाद किसी भी पाठ को काट देता है। खैर, वास्तव में, मुझे 6१ ९ ६ अक्षर मिले, और ,१ ९ ६ के बाद, तो यह मुझे किसी भी प्रकार टाइप नहीं करने देगा।

यहां एक स्क्रिप्ट है जो यह परीक्षण करेगी कि आप कितने समय तक एक स्टेटमेंट का उपयोग कर सकते हैं। ठीक है, यह मानते हुए कि आपके पास 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 वर्ण है।
एलेस्टेयर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.