2010-11-14 6 views
8

मैं सी कोड का एक टुकड़ा विकसित कर रहा हूं जो विंडोज़ में निर्देशिका के तहत परिवर्तनों की निगरानी के लिए ReadDirectoryChangesW() का उपयोग करता है। मैंने ReadDirectoryChangesW() और FILE_NOTIFY_INFORMATION संरचना के साथ-साथ दस्तावेज़ों के कई अन्य टुकड़ों के लिए संबंधित एमएसडीएन प्रविष्टियां पढ़ी हैं। इस बिंदु पर मैंने निगरानी में स्वयं की कोई स्पष्ट समस्या के साथ कई निर्देशिकाओं की निगरानी करने में कामयाब रहे हैं। समस्या यह है कि इस फ़ंक्शन द्वारा FILE_NOTIFY_INFORMATION संरचना में डाले गए फ़ाइल नाम कैनोनिकल नहीं हैं।विंडोज़ 'ReadDirectoryChangesW() और इसके मिश्रित लंबे/लघु फ़ाइल नाम आउटपुट से कैसे निपटें?

एमएसडीएन के अनुसार वे या तो लंबे या छोटे रूप में हो सकते हैं। मुझे कई पद मिले हैं जो इस मामले को संभालने के लिए छोटे और लंबे पथनाम दोनों को कैशिंग करने का सुझाव देते हैं। दुर्भाग्यवश, विंडोज 7 सिस्टम पर अपने स्वयं के परीक्षण के अनुसार यह इस मुद्दे को खत्म करने के लिए पर्याप्त नहीं है, क्योंकि प्रत्येक फ़ाइल नाम के लिए केवल दो विकल्प नहीं हैं। समस्या यह है कि पथनाम में प्रत्येक घटक या तो लंबे या छोटे रूप में हो सकता है।

सी: निम्नलिखित pathnames सभी एक ही फ़ाइल को संदर्भित कर सकता \ कार्यक्रम ~ 1 \ MYPROG ~ 1 \ MyData ~ 1.TXT

c: \ कार्यक्रम ~ 1 \ MYPROG ~ 1 \ MyDataFile.txt

c: \ कार्यक्रम ~ 1 \ MyProgram \ MyData ~ 1.TXT

c: \ कार्यक्रम ~ 1 \ MyProgram \ MyDataFile.txt

c: \ Program Files \ MYPROG ~ 1 \ MyData ~ 1 .TXT

...

और जहां तक ​​मैं cmd.exe का उपयोग करके अपने परीक्षण से बता सकता हूं वे सभी पूरी तरह से स्वीकार्य हैं। अनिवार्य रूप से, प्रत्येक फ़ाइल के लिए वैध पथनामों की संख्या इसके पथनाम में घटकों की संख्या के साथ घातीय हो जाती है।

दुर्भाग्यवश, ReadDirectoryChangesW() फ़ाइल आउटपुट के साथ अपने आउटपुट बफर को भरने के लिए प्रतीत होता है जैसा सिस्टम ऑपरेशन के लिए प्रदान किया जाता है जो प्रत्येक ऑपरेशन का कारण बनता है। उदाहरण के लिए यदि आप cm.t.exe कमांड का उपयोग, नाम बदलने, e.t.c. को हटाने के लिए करते हैं। फ़ाइलों, FILE_NOTIFY_INFORMATION में कमांड लाइन पर निर्दिष्ट फ़ाइल नाम होंगे।

अब, ज्यादातर मामलों में मैं GetLongPathName() और दोस्तों का उपयोग अपने उपयोग के लिए एक अद्वितीय मार्ग प्राप्त करने के लिए कर सकता था। दुर्भाग्यवश, फ़ाइलों को हटाते समय नहीं किया जा सकता - जब तक मुझे अधिसूचना मिलती है, फ़ाइल पहले ही समाप्त हो चुकी है और Get * PathName() फ़ंक्शन काम नहीं करेंगे।

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

ऐसा करने के लिए एक आसान तरीका के लिए कोई सुझाव?

पीएस 1: जबकि चेंज जर्नल इस प्रभावी ढंग से निपटेंगे (मुझे उम्मीद है) मुझे विश्वास नहीं है कि मैं एनटीएफएस से अपने संबंधों और मेरे आवेदन के लिए प्रशासक निजीकरण की कमी के कारण उनका उपयोग कर सकता हूं। मैं वहां नहीं जाऊंगा, जब तक कि मुझे पूरी तरह मजबूर नहीं किया जाता।

पीएस 2: कृपया ध्यान रखें कि मैं यूनिक्स पर मुख्य रूप से कोड में रखने के लिए, तो कोमल हो ...

+0

यदि अन्य सभी विफल हो जाते हैं, तो शायद एक मिनीफिल्टर ड्राइवर काम करेगा? – wj32

+0

मुझे विश्वास है कि यही एंटीवायरस प्रोग्राम करता है और मुझे लगता है कि यह इस मुद्दे का समाधान होगा। दुर्भाग्यवश इसे स्थापित करने के लिए सिस्टम प्रशासक अधिकारों की आवश्यकता है, और चेंज जर्नल की तरह यह मेरे आवेदन की वास्तुकला को बहुत अधिक जटिल बना देगा, क्योंकि मुझे सुरक्षा और स्थिरता के मुद्दों पर विचार करना होगा जिन्हें मुझे अब निपटना नहीं है। और किसी भी ओएस के लिए कर्नेल-मोड या अर्ध-कर्नेल-मोड ड्राइवर लिखने की अंतर्निहित कठिनाइयों को न भूलें। – thkala

+0

ओह, और फिलहाल यह कुछ उपयोगकर्ता निर्देशिकाओं को देखने के लिए बस सबकुछ की निगरानी करने के लिए एक ओवरकिल लगता है। हालांकि सुझाव के लिए धन्यवाद ... – thkala

उत्तर

1

आप हर संयोजन कैश करने के लिए जरूरत नहीं है। यह तब होगा यदि आप प्रत्येक उपपथ को लंबे रूप में परिवर्तित करने में सक्षम होने के लिए कैश करते हैं।उदाहरण दुकान इस के लिए:

  • C:\PROGRA~1 => c:\Program Files
  • c:\Program Files\MYPROG~1 => c:\Program Files\MyProgram
  • c:\Program Files\MyProgram\MYDATA~1.TXT => c:\Program Files\MyProgram\MyDataFile.txt
  • c:\Program Files\MyProgram\MYDATA~2.TXT => c:\Program Files\MyProgram\MyDataFile2.txt

अब अगर आप c:\PROGRA~1\MYPROG~1\MYDATA~1.TXT की कोई सूचना मिलती है, यह हर \ में विभाजित है, और के लिए प्रत्येक भाग देखने यह लंबा रूप है।

भूलें कि MyDataFile.txt और MYDATAFILE.TXT भी एक ही फ़ाइल को इंगित करते हैं। तो केस-असंवेदनशील की तुलना करें या सब कुछ अपरकेस में कनवर्ट करें।

और यदि c:\PROGRA~1\MYPROG~1\MYDATA~1.TXT हटा दिया गया है, तो आप GetLongPathName()c:\PROGRA~1\MYPROG~1 पर अभी भी उपयोग कर सकते हैं।

+0

जब मैंने व्यापक कैशिंग और डेटा खनन का उल्लेख किया तो मुझे आपके द्वारा प्रस्तावित प्रस्तावों का एक और अधिक उन्नत संस्करण दिमाग में था। अभी उपलब्ध होने पर मैं छोटे और लंबे दोनों नामों को संग्रहीत कर रहा हूं और जब कोई पथ देखा गया है, तो मैं पहले से ही सभी वैकल्पिक पथनामों को ढूंढ सकता हूं। सी का उपयोग करना: \ ए \ बी \ सी -> सी: \ a \ b \ c एसोसिएशन मैं सभी सी: \ {ए, ए} \ {बी, बी} \ {सी, सी} संयोजनों का पता लगा सकता हूं। अदृश्य फ़ाइलों को हटाने के साथ अभी भी एक समस्या मौजूद है। मैं इस बात से निपटने के लिए निर्देशिका की प्रारंभिक स्थिति को पुन: संग्रहित करने के बारे में सोच रहा हूं - सुनिश्चित नहीं है कि मैं इसे किसी भी तरह से टाल सकता हूं ... – thkala

संबंधित मुद्दे