2010-08-09 7 views
6

फसल है I डेल्फी 2010 का उपयोग कर रहा हूं और मेरा प्रोग्राम सिस्टम का अस्थायी पथ प्राप्त करना चाहता है। मैं TPath.GetTempPath का उपयोग कर रहा हूं और सब कुछ ठीक काम कर रहा है ... कम से कम मेरे और मेरे सहकर्मियों के लिए। लेकिन कुछ ग्राहक मशीनों पर यह विधि एक फसल पथ लौटाती है जो (बेशक) मौजूद नहीं है। मुझे पता चला कि यह समस्या GetLongPathName() को अंतर्निहित कॉल का परिणाम प्रतीत होती है।डेल्फी TPath.GetTempPath परिणाम

पूरा कोड इस तरह दिखता है:

[...] 
var 
TmpDir : String; 
Len : Integer; 
begin 

[... Call to GetTempPath succeeds and we have a valid temp directory in short "~" notation in var TmpDir ...] 

Len := GetLongPathName(PChar(TmpDir), nil, 0);  // Len = 37 
    SetLength(TmpDir, Len - 1);       // We want to set the len of TmpDir to 37 - 1. 
    GetLongPathName(PChar(TmpDir), PChar(TmpDir), Len); // Only 32 (instead of 36) characters are copied - so we have a cropped path - But why?! 

end; 
[...] 

यह केवल कुछ सिस्टम पर होता है और मैं पता नहीं क्यों। मुझे इसके लिए एक बुरा कामकाज मिला, लेकिन मैं जानना चाहता हूं कि यहां क्या हो रहा है।

क्या कोई इस पर कुछ प्रकाश डाल सकता है?

+0

क्या आप हमें सही (अपेक्षित) और बुरे (वास्तविक) पथ नामों के उदाहरण दे सकते हैं? क्या यह एक यूनिकोड या एन्कोडिंग मुद्दा हो सकता है? –

+0

हमने सोचा कि यह भी पहले स्थान पर है, लेकिन पथ नामों में कोई वर्ण नहीं है जो यूनिकोड रूपांतरणों के साथ समस्याएं पैदा कर सकता है। GetLongPathName का परिणाम पथ नाम केवल अंतिम 4 वर्ण ("Temp \" का "emp \") गायब है - अन्य सभी वर्ण मान्य हैं। – Patrick

+0

लगता है जैसे http://qc.embarcadero.com/wc/qcmain.aspx?d=92006 –

उत्तर

4

वहाँ होमलैंड सुरक्षा पृष्ठों पर यह Windows API फ़ंक्शन के बारे में एक नोट है:

" GetLongPathName() और इसी तरह के कार्यों के लिए बदले बफर एक छोटा कर दिया पथ लौट सकते हैं और करने के लिए कड़ी मेहनत से पैदा हो सकता है त्रुटियों को समझें। "

https://buildsecurityin.us-cert.gov/bsi-rules/home/g1/753-BSI.html

आप स्रोत कोड है, तो आप की जांच कर सकता है, तो समस्या इस आलेख में वर्णित डेल्फी 2010 कार्यान्वयन में मौजूद है।

+0

आप सही हैं, मैंने यह भी पाया और मेरा "बुरा कामकाज" शुरू में लेन को अधिकतम MAX_PATH सेट करना और GetLongPathName के परिणाम की जांच करना है(), लेकिन मुझे आश्चर्य है कि क्यों Embarcadero अन्य दृष्टिकोण का उपयोग कर रहा है ... लेकिन इसे पोस्ट करने के लिए धन्यवाद, क्योंकि यह मेरे दृष्टिकोण को सत्यापित करता है। – Patrick

+0

आपको इसे क्यूसी को रिपोर्ट करनी चाहिए। –

+1

तो समस्या क्या है? प्रश्न में कोड सही ढंग से फ़ंक्शन को दो बार कॉल करता है, है ना? वास्तविक लंबाई के लिए बफर भरने के लिए आवश्यक लंबाई और फिर दूसरी बार पता लगाने के लिए। आपके द्वारा उद्धृत कोड पहले बफर आवंटित करता है ताकि फ़ंक्शन पर पहला कॉल काम कर सके, लेकिन यदि यह विफल हो जाता है, तो यह एक नया बफर आवंटित करता है और इसके बजाए इसका उपयोग करता है। क्या यह वास्तव में एक महत्वपूर्ण अंतर है? आलेख यह मानने के खिलाफ चेतावनी दे रहा है कि अधिकतम कॉल हमेशा MAX_PATH आकार के बफर दिए जाने पर सफल होगा। इस स्थिति पर यह चेतावनी कैसे लागू होती है? –

3

अगर आप कोशिश क्या होता है:

var 
    longpath : string; 

SetLength(longpath,MAX_PATH); 
SetLength(longpath, GetLongPathName(PChar(TmpDir),PChar(LongPath),MAX_PATH)); 

यह मेरे लिए काम किया, अपने संस्करण पथ छोटा कर दिया।

+0

मैं अपने "कामकाज" में यही कर रहा हूं - यदि आपकी मशीन पर समस्या होती है: तो यह दिलचस्प होगा अगर TPath.GetTempPath() फ़ंक्शन आपके लिए काम कर रहा है? – Patrick

+1

यह कोड आपको एक स्ट्रिंग के साथ छोड़ सकता है जो Max_Path से अधिक है, लेकिन केवल Max_Path वर्णों को असाइन किया गया है। यही है, 'लंबाई (लांगपाथ)> स्ट्रेलन (पीसीहर (लांगपाथ)) '। आपको कचरे के साथ एक स्ट्रिंग के साथ भी छोड़ा जा सकता है - डॉक्स यह नहीं कहता कि बफर में फ़ंक्शन कितना छोटा होता है जब बफर बहुत छोटा होता है। सुरक्षा बुलेटिन और दस्तावेज दोनों उस समस्या से बचने के तरीके का वर्णन करते हैं। –

+0

ठीक है, हमें यहां उल्लेख करना चाहिए कि GetLongPathName का वापसी मूल्य महत्वपूर्ण है और इसकी जांच की जानी चाहिए। – Patrick