अब .NET CLR 4.0 साइड बाय साइड (एसएक्सएस) ऑपरेशन का समर्थन करता है, अब प्रबंधित कोड में खोल एक्सटेंशन लिखना संभव होना चाहिए। मैंने इसका प्रयास किया है और एक संपत्ति हैंडलर सफलतापूर्वक कोड किया है जो आईप्रॉपर्टीस्टोर, IInitializeWithStream और IPropertyStoreCapabilities लागू करता है।प्रबंधित संपत्ति हैंडलर शैल एक्सटेंशन को लागू करने का सही तरीका क्या है?
हैंडलर ठीक काम करता है और एक्सप्लोरर के माध्यम से फ़ाइलों को ब्राउज़ करते समय अपेक्षित कहा जाता है। यह पूर्वावलोकन पैनल में कस्टम गुणों और फ़ाइल गुणों "विवरण" पैनल को प्रदर्शित करने में भी ठीक काम करता है।
हालांकि, जब मैं को पूर्वावलोकन पैनल में एक संपत्ति संपादित करने का प्रयास करता हूं, और उसके बाद "सहेजें" पर क्लिक करें, तो मुझे "फ़ाइल उपयोग में" त्रुटि मिलती है, यह कहते हुए कि फ़ाइल Windows Explorer में खुलती है।
कुछ छोटी-मोटी बातें:
- जब एक्सप्लोरर कॉल IInitializeWithStream.Initialize STGM संपत्ति STGM_SHARE_DENY_WRITE को तैयार है।
- और किसी भी समय एक्सप्लोरर को IPropertyStore.SetValue या IPropertyStore.Commit कॉल नहीं किया गया।
- मुझे एक ही फ़ाइल गुणों के लिए अलग-अलग धागे पर मेरे हैंडलर को दोहराया गया कॉल दिखाई देता है।
तो संपत्ति को काम करने के लिए मुझे क्या बदलने की आवश्यकता है (या रजिस्टर में सेट)?
अद्यतन:
बेन के लिए धन्यवाद मैं काम कर रहा यह मिल गया है। "कठिन हिस्सा" (कम से कम मेरे लिए) यह समझ रहा था कि COM इंटरऑप कभी भी मेरे प्रॉपर्टी हैंडलर पर निपटान या अंतिम रूप देने को कॉल नहीं करेगा। यह उन फ़ाइलों को छोड़ रहा था जिन्हें मैंने जीसी चलाने तक संसाधित किया था।
सौभाग्य से, "प्रॉपर्टी हैंडलर प्रोटोकॉल" इस तरह काम करता है कि जब IInitializeWithSream.Initialize() को ReadValue() के लिए बुलाया जाता है तो स्ट्रीममोड केवल पढ़ने के लिए कहा जाता है, और जब इसे SetValue() के लिए कहा जाता है तो स्ट्रीममोड ReadWrite और Commit () अंत में बुलाया जाएगा।
int IInitializeWithStream.Initialize(IStream stream, uint grfMode)
{
_stream = stream;
_streamMode = (Stgm)grfMode;
Load();
// We release here cause if this is a read operation we won't get called back,
// and our finializer isn't called.
if ((_streamMode & Stgm.ReadWrite) != Stgm.ReadWrite)
{
Marshal.ReleaseComObject(_stream);
_stream = null;
}
return HResult.S_OK;
}
int IPropertyStore.Commit()
{
bool result = false;
if (_stream != null)
{
result = WriteStream(_stream);
Marshal.ReleaseComObject(_stream);
_stream = null;
}
return result ? HResult.S_OK : HResult.E_FAIL;
}
कोई पूर्वावलोकन हैंडलर नहीं है, लेकिन Windows खोज सेवा कभी कभी हैंडलर लोड करने के लिए लगता है। लेकिन यह फ़ाइल को लॉक नहीं करना चाहिए? इसके अलावा, मैं IInitializeWithFile का उपयोग करने के लिए स्विच करके संपादन कार्य कर सकता हूं, और मेरे SaveValue() और Commit() को अपेक्षित के रूप में कॉल किया जा सकता है। वैसे भी, यहां तक कि जब मैं IInitializeWithStream बाहर ठूंठ इतना है कि यह कभी नहीं धारा का उपयोग करता है (और getValue() वापसी डिफ़ॉल्ट खाली मान हैं) यह अभी भी जब एक संपत्ति संपादन एक ही त्रुटि देता है। एक्सप्लोरर कभी भी SaveValue() या Commit() को कॉल नहीं करता है। –
क्या मुझे Addref() ISTream की आवश्यकता है जिसे मैं प्रारंभ() में प्राप्त करता हूं? और फिर Commit() के बाद इसे रिलीज़()? मैंने माना था कि मैंने नहीं किया था। आपके आखिरी मुद्दे के अनुसार मैंने सोचा कि पक्ष में साइड मोड में .NET 4.0 का उपयोग करके सीएलआर संस्करण को हल एक्सटेंशन के साथ हल किया गया है। मैंने सत्यापित किया है कि सही सीएलआर मेरा कोड चला रहा है। –