This question इस बिंदु पर चर्चा शुरू की, और कुछ परीक्षण यह निर्धारित करने के लिए क्यों किया गया था। तो, cmd.exe
अंदर कुछ डिबगिंग के बाद ... (यह एक 32 बिट Windows XP cmd.exe के लिए है, लेकिन के रूप में व्यवहार नए सिस्टम संस्करण पर संगत है, शायद एक या समान कोड प्रयोग किया जाता है)
अंदर जेब के उत्तर कहा गया है
It's a problem with the quotes and %~0.
cmd.exe handles %~0 in a special way
और यहां जेब सही है।
चल रहे बैच फ़ाइल के वर्तमान संदर्भ के अंदर वर्तमान बैच फ़ाइल का एक संदर्भ है, एक "चर" जिसमें पूर्ण पथ और चलने वाली बैच फ़ाइल का फ़ाइल नाम है।
जब एक चर एक्सेस किया जाता है, अपने मूल्य उपलब्ध चरों की सूची से लिया गया है, लेकिन चर का अनुरोध किया %0
है, और कुछ संशोधक अनुरोध किया गया है (~
प्रयोग किया जाता है) तो चल बैच संदर्भ में डेटा है, तो "चर" प्रयोग किया जाता है।
लेकिन ~
का उपयोग चरों में एक और प्रभाव है। यदि मूल्य उद्धृत किया गया है, तो उद्धरण हटा दिए जाते हैं। और यहां कोड में एक बग है। यह (स्यूडोकोड करने के लिए यहाँ सरलीकृत कोडांतरक)
value = varList[varName]
if (value && value[0] == quote){
value = unquote(value)
} else if (varName == '0') {
value = batchFullName
}
और हाँ, इसका मतलब है कि जब बैच फ़ाइल उद्धृत किया गया है, if
के पहले भाग निष्पादित किया जाता है और बैच फ़ाइल के लिए पूर्ण संदर्भ नहीं है की तरह कुछ कोडित है उपयोग किया जाता है, इसके बजाय मूल्य को पुनर्प्राप्त करने के लिए बैच फ़ाइल को संदर्भित करने के लिए उपयोग की जाने वाली स्ट्रिंग होती है।
तब क्या होता है? अगर बैच फ़ाइल को पूर्ण पथ कहा जाता था, तो कोई समस्या नहीं होगी। लेकिन यदि कॉल में पूर्ण पथ का उपयोग नहीं किया जाता है, तो बैच कॉल में मौजूद पथ में मौजूद किसी भी तत्व को पुनर्प्राप्त करने की आवश्यकता नहीं है। यह पुनर्प्राप्ति सापेक्ष पथ मानती है।
एक साधारण बैच फ़ाइल (test.cmd
)
@echo off
echo %~f0
जब test
(कोई विस्तार, कोट के बिना) का उपयोग करते हुए कहा जाता है, हम c:\somewhere\test.cmd
प्राप्त जब "test"
(कोई विस्तार, उद्धरण) का उपयोग कर कहा जाता है, हम प्राप्त c:\somewhere\test
पहले मामले में, उद्धरण के बिना, सही आंतरिक मान का उपयोग किया जाता है। दूसरे मामले में, जैसे कॉल उद्धृत किया गया है, बैच फ़ाइल ("test"
) को कॉल करने के लिए उपयोग की जाने वाली स्ट्रिंग निर्विवाद और उपयोग की जाती है। चूंकि हम एक पूर्ण पथ का अनुरोध कर रहे हैं, इसे test
नामक किसी चीज़ का सापेक्ष संदर्भ माना जाता है।
यही कारण है कि। कैसे हल करें?
सी # कोड
उद्धरण का उपयोग न करें से: cmd /c batchfile.cmd
तो उद्धरण की जरूरत है, बैच फ़ाइल को कॉल में पूर्ण पथ का उपयोग करें। इस तरह %0
में सभी आवश्यक जानकारी शामिल हैं।
बैच फ़ाइल
बैच फ़ाइल किसी भी स्थान से किसी भी तरह से लागू किया जा सकता है से । वर्तमान बैच फ़ाइल की जानकारी को पुनर्प्राप्त करने का एकमात्र विश्वसनीय तरीका एक सबराउटिन का उपयोग करना है। यदि कोई संशोधक (~
) का उपयोग किया जाता है, तो %0
डेटा प्राप्त करने के लिए आंतरिक "चर" का उपयोग करेगा।
@echo off
setlocal enableextensions disabledelayedexpansion
call :getCurrentBatch batch
echo %batch%
exit /b
:getCurrentBatch variableName
set "%~1=%~f0"
goto :eof
यह independtly कैसे आप के साथ या बिना उद्धरण चिह्नों, फ़ाइल फोन की वर्तमान बैच फ़ाइल का पूर्ण पथ सांत्वना देने गूंज होगा।
नोट: यह क्यों काम करता है? एक subroutine के अंदर %~f0
संदर्भ एक अलग मूल्य क्यों देता है? Subroutine के अंदर से प्राप्त डेटा समान नहीं है। जब call
निष्पादित किया जाता है, तो स्मृति में एक नया बैच फ़ाइल संदर्भ बनाया जाता है, और आंतरिक "चर" का उपयोग इस संदर्भ को आरंभ करने के लिए किया जाता है।
जब आप बैच को 'cmd' से' mybatfile.cmd "' (हाँ, * * उद्धरण के साथ) चलाते हैं तो आप व्यवहार को दोहरा सकते हैं। 'Process.Start' के माध्यम से चलते समय आपको यह आविष्कार मिलता है जैसा कि आप' echo'ing '% 0' द्वारा भी सत्यापित कर सकते हैं। – Joey
धन्यवाद एक लॉय जॉय, आपके सुझावों ने चाल की। यह अब मेरे लिए काम करता है। –
ठीक है, यह सिर्फ एक अवलोकन था; मैं अभी भी व्यवहार की व्याख्या नहीं कर सकता :-) – Joey