IOException: प्रक्रिया फ़ाइल 'फ़ाइल पथ' तक नहीं पहुँच सकती क्योंकि इसका उपयोग किसी अन्य प्रक्रिया द्वारा किया जा रहा है


172

मेरे पास कुछ कोड हैं और जब यह निष्पादित होता है, तो यह IOExceptionकहकर फेंकता है कि

प्रक्रिया फ़ाइल 'फ़ाइलनाम' तक नहीं पहुँच सकती क्योंकि इसका उपयोग किसी अन्य प्रक्रिया द्वारा किया जा रहा है

इसका क्या मतलब है, और मैं इसके बारे में क्या कर सकता हूं?


1
फ़ाइल का उपयोग करने वाली अन्य प्रक्रिया को खोजने के लिए इस प्रश्न को देखें ।
पेट

जवाबों:


274

कारण क्या है?

त्रुटि संदेश बहुत स्पष्ट है: आप एक फ़ाइल का उपयोग करने का प्रयास कर रहे हैं, और यह सुलभ नहीं है क्योंकि एक अन्य प्रक्रिया (या यहां तक ​​कि एक ही प्रक्रिया) इसके साथ कुछ कर रही है (और यह किसी भी साझाकरण की अनुमति नहीं देता)।

डिबगिंग

आपके विशिष्ट परिदृश्य के आधार पर इसे हल करना (या समझना बहुत कठिन) आसान हो सकता है। चलो कुछ देखते हैं।

आपकी प्रक्रिया उस फ़ाइल को एक्सेस करने के लिए केवल एक ही है
आप सुनिश्चित करें कि अन्य प्रक्रिया आपकी अपनी प्रक्रिया है। यदि आप जानते हैं कि आप उस फ़ाइल को अपने प्रोग्राम के किसी अन्य भाग में खोलते हैं, तो सबसे पहले आपको यह जाँचना होगा कि आप प्रत्येक उपयोग के बाद फ़ाइल हैंडल को ठीक से बंद कर दें। यहाँ इस बग के साथ कोड का एक उदाहरण दिया गया है:

var stream = new FileStream(path, FileAccess.Read);
var reader = new StreamReader(stream);
// Read data from this file, when I'm done I don't need it any more
File.Delete(path); // IOException: file is in use

सौभाग्य से FileStreamलागू होता है IDisposable, इसलिए एक usingबयान के अंदर अपने सभी कोड को लपेटना आसान है :

using (var stream = File.Open("myfile.txt", FileMode.Open)) {
    // Use stream
}

// Here stream is not accessible and it has been closed (also if
// an exception is thrown and stack unrolled

यह पैटर्न यह भी सुनिश्चित करेगा कि अपवाद के मामले में फ़ाइल को खुला नहीं छोड़ा जाएगा (यह कारण हो सकता है कि फ़ाइल उपयोग में है: कुछ गलत हो गया, और किसी ने इसे बंद नहीं किया; इस पोस्ट को देखें; उदाहरण के लिए को )।

यदि सब कुछ ठीक लगता है (आप निश्चित रूप से अपवाद के मामले में भी हमेशा आपके द्वारा खोली गई हर फ़ाइल को बंद करते हैं) और आपके पास कई काम करने वाले धागे हैं, तो आपके पास दो विकल्प हैं: फ़ाइल एक्सेस प्राप्त करने के लिए अपने कोड को फिर से काम करें (हमेशा करने योग्य नहीं और हमेशा नहीं चाहता था) या एक रिट्री पैटर्न लागू करें । यह आई / ओ संचालन के लिए एक बहुत ही सामान्य पैटर्न है: आप कुछ करने की कोशिश करते हैं और त्रुटि के मामले में आप प्रतीक्षा करते हैं और फिर से प्रयास करते हैं (क्या आपने खुद से पूछा है, उदाहरण के लिए, विंडोज शेल को आपको सूचित करने में कुछ समय लगता है कि एक फ़ाइल उपयोग में है और हटाया नहीं जा सकता?) C # में इसे लागू करना बहुत आसान है ( डिस्क I / O , नेटवर्किंग और डेटाबेस एक्सेस के बारे में बेहतर उदाहरण देखें )।

private const int NumberOfRetries = 3;
private const int DelayOnRetry = 1000;

for (int i=1; i <= NumberOfRetries; ++i) {
    try {
        // Do stuff with file
        break; // When done we can break loop
    }
    catch (IOException e) when (i <= NumberOfRetries) {
        // You may check error code to filter some exceptions, not every error
        // can be recovered.
        Thread.Sleep(DelayOnRetry);
    }
}

कृपया एक सामान्य त्रुटि पर ध्यान दें जो हम StackOverflow पर अक्सर देखते हैं:

var stream = File.Open(path, FileOpen.Read);
var content = File.ReadAllText(path);

इस स्थिति ReadAllText()में विफल हो जाएगा क्योंकि फ़ाइल उपयोग में है ( File.Open()पहले की पंक्ति में)। फाइल को पहले से खोलना न केवल अनावश्यक है बल्कि गलत भी है। एक ही सभी पर लागू होता है Fileकार्यों है कि एक नहीं लौटते संभाल फ़ाइल आप काम कर रहे हैं: File.ReadAllText(), File.WriteAllText(), File.ReadAllLines(), File.WriteAllLines()और दूसरों (जैसे File.AppendAllXyz()कार्यों) सभी खुले और बंद अपने आप फ़ाइल होगा।

आपकी प्रक्रिया उस फ़ाइल तक पहुँचने के
लिए एकमात्र नहीं है यदि आपकी प्रक्रिया उस फ़ाइल तक पहुँचने के लिए एकमात्र नहीं है, तो बातचीत कठिन हो सकती है। एक रिट्री पैटर्न में मदद मिलेगी (यदि फ़ाइल किसी और के द्वारा नहीं खोली जानी चाहिए लेकिन यह है, तो आपको एक उपयोगिता की आवश्यकता है कि प्रक्रिया एक्सप्लोरर जैसी जांच करें कि कौन क्या कर रहा है )।

बचने के तरीके

लागू होने पर, हमेशा फाइलों को खोलने के लिए बयानों का उपयोग करें। जैसा कि पिछले पैराग्राफ में कहा गया है, यह सक्रिय रूप से आपको कई सामान्य त्रुटियों से बचने में मदद करेगा ( इस पोस्ट को उदाहरण के लिए देखें कि इसका उपयोग कैसे न करें )।

यदि संभव हो, तो यह तय करने का प्रयास करें कि कौन विशिष्ट फ़ाइल तक पहुंच रखता है और कुछ प्रसिद्ध तरीकों के माध्यम से पहुंच को केंद्रीकृत करता है। यदि, उदाहरण के लिए, आपके पास एक डेटा फ़ाइल है जहां आपका प्रोग्राम पढ़ता है और लिखता है, तो आपको एक एकल वर्ग के अंदर सभी I / O कोड को बॉक्स करना चाहिए। यह डिबग को आसान बना देगा (क्योंकि आप हमेशा वहां एक ब्रेकपॉइंट डाल सकते हैं और देख सकते हैं कि कौन क्या कर रहा है) और यह भी कि एकाधिक एक्सेस के लिए यह सिंक्रोनाइज़ेशन पॉइंट (यदि आवश्यक हो) होगा।

भूल जाओ मैं / ओ संचालन हमेशा विफल हो सकता है, एक आम उदाहरण यह है:

if (File.Exists(path))
    File.Delete(path);

अगर कोई फ़ाइल को File.Exists()पहले लेकिन बाद में हटाता है File.Delete(), तो यह एक IOExceptionऐसी जगह फेंक देगा जहां आप गलत तरीके से सुरक्षित महसूस कर सकते हैं।

जब भी संभव हो, एक रिट्री पैटर्न लागू करें , और यदि आप उपयोग कर रहे हैं, तो FileSystemWatcherकार्रवाई स्थगित करने पर विचार करें (क्योंकि आप अधिसूचित हो जाएंगे, लेकिन एक एप्लिकेशन अभी भी उस फ़ाइल के साथ विशेष रूप से काम कर सकता है)।

उन्नत परिदृश्य
यह हमेशा इतना आसान नहीं होता है, इसलिए आपको किसी और के साथ साझा करने की आवश्यकता हो सकती है। यदि, उदाहरण के लिए, आप शुरुआत से लेकर अंत तक पढ़ रहे हैं, तो आपके पास कम से कम दो विकल्प हैं।

1) FileStreamउचित सिंक्रनाइज़ेशन फ़ंक्शन के साथ समान साझा करें (क्योंकि यह थ्रेड-सुरक्षित नहीं है )। यह और यह देखें एक उदाहरण के लिए पदों।

2) FileShareसमान फ़ाइल को समान रूप से एक्सेस करने के लिए अन्य प्रक्रियाओं (या अपनी प्रक्रिया के अन्य भागों) की अनुमति देने के लिए ओएस को निर्देश देने के लिए गणना का उपयोग करें ।

using (var stream = File.Open(path, FileMode.Open, FileAccess.Write, FileShare.Read))
{
}

इस उदाहरण में मैंने दिखाया कि पढ़ने के लिए एक फ़ाइल कैसे खोलें और पढ़ने के लिए साझा करें; कृपया ध्यान दें कि जब पढ़ना और लिखना ओवरलैप होता है, तो इसका परिणाम अपरिभाषित या अमान्य डेटा होता है। यह एक ऐसी स्थिति है जिसे पढ़ते समय संभाला जाना चाहिए। यह भी ध्यान दें कि यह streamथ्रेड-सेफ़ तक पहुंच नहीं बनाता है , इसलिए इस ऑब्जेक्ट को कई थ्रेड्स के साथ साझा नहीं किया जा सकता है जब तक कि एक्सेस किसी तरह से सिंक्रनाइज़ न हो (अन्य लिंक देखें)। अन्य साझाकरण विकल्प उपलब्ध हैं, और वे अधिक जटिल परिदृश्य खोलते हैं। अधिक जानकारी के लिए कृपया MSDN को देखें।

सामान्य एन प्रक्रियाओं में सभी एक साथ एक ही फ़ाइल से पढ़ सकते हैं, लेकिन केवल एक ही लिखना चाहिए, एक नियंत्रित परिदृश्य में आप समवर्ती लेखन को सक्षम कर सकते हैं लेकिन इस उत्तर के अंदर कुछ पाठ पैराग्राफ में इसे सामान्यीकृत नहीं किया जा सकता है।

क्या किसी अन्य प्रक्रिया द्वारा उपयोग की गई फ़ाइल को अनलॉक करना संभव है ? यह हमेशा सुरक्षित नहीं है और इतना आसान नहीं है लेकिन हां, यह संभव है


मुझे नहीं पता कि मेरे कोड में क्या गड़बड़ी है, मैं ब्लॉक का उपयोग कर रहा हूं, लेकिन फिर भी एक त्रुटि कह रही है कि जब मैं इसे हटाने की कोशिश कर रहा हूं तो फाइल उपयोग में है।
जमशेद कामरान

नहीं, वास्तव में मेरे पास टाइमर नियंत्रण है जो टाइमर के बगल में है, अगर मैं फ़ंक्शन को फिर से कॉल करता हूं तो यह एक अपवाद फेंक देगा। मूल रूप से मैं एक फ़ाइल को किसी अन्य पाठ फ़ाइल में डिक्रिप्ट कर रहा हूं, उसके बाद नई बनाई गई फ़ाइल को हटा रहा है, जो कि विलोपन पर अपवाद को फेंकता है!
जमशेद कामरान

3
@ جمشیدکامران अपने कोड में आपके पास मौजूद सामग्री के साथ फ़ाइल क्यों बनाएं, फिर इसे हटाएं? पहली बार में फ़ाइल बनाने के लिए अजीब लगता है, फिर। चूंकि आपने कोड पोस्ट नहीं किया, इसलिए हमें नहीं पता कि आप क्या कर रहे हैं। लेकिन जब आप अपनी फ़ाइल बनाते हैं, अगर आप इसे करते हैं, तो आपको इसे लिखने से पहले उस के अंत में File.Create(path)जोड़ना चाहिए .Close()usingफ़ाइलों को लिखने के लिए बयानों के अलावा , उसके बाद नष्ट होने जैसे नुकसान भी हैं । आपको अपने प्रश्न में कोड पोस्ट करना चाहिए कि आप अपनी फ़ाइल कैसे बना रहे हैं और कैसे हटा रहे हैं। लेकिन शायद ऊपर बताई गई किसी चीज के अनुरूप है।
vapcguy

मेरा कोड उपयोग करता है, Directory.SetCreationTimeUTC()लेकिन यह तब विफल हो जाता है जब फ़ाइल एक्सप्लोरर खुला होता है, यह दावा करते हुए कि निर्देशिका को किसी अन्य प्रक्रिया द्वारा एक्सेस किया जा रहा है। मुझे इस स्थिति को कैसे संभालना चाहिए?
काइल डेलानी

1
@KyleDelaney मैं कहूंगा कि आपको फ़ोल्डर बंद होने तक प्रतीक्षा करने की आवश्यकता है, अगर यह कुछ सेकंड की बात नहीं है, तो सब कुछ जल्दी से जटिल हो जाएगा (लंबित संचालन के साथ एक पृष्ठभूमि कतार रखें? फ़ाइल सिस्टम वॉचर? मतदान?) आप चाहते हो सकता है एड-हॉक उत्तर के लिए अधिक विवरण के साथ एक प्रश्न पोस्ट करें
एड्रियानो रिपेट्टी

29

फ़ाइलशेयर का उपयोग करने से मेरी फ़ाइल खोलने की समस्या ठीक हो गई, भले ही इसे किसी अन्य प्रक्रिया द्वारा खोला गया हो।

using (var stream = File.Open(path, FileMode.Open, FileAccess.Write, FileShare.ReadWrite))
{
}

9

एक छवि अपलोड करते समय एक समस्या थी और इसे हटा नहीं सका और एक समाधान मिला। gl hf

//C# .NET
var image = Image.FromFile(filePath);

image.Dispose(); // this removes all resources

//later...

File.Delete(filePath); //now works

2
यदि आप किसी फ़ाइल को हटा रहे हैं, तो आपको पहले इमेज ऑब्जेक्ट को डिस्पोज़ करना होगा।
शाज़िया

1
अच्छा लगा, मैंने इस समाधान की तलाश की। मुझे Image.FromFile फ़ंक्शन के साथ भी एक समस्या थी।
वंशज

1
@thescion :) np
हडसन

1
इसने मेरे लिए शानदार काम किया और मेरी सटीक समस्या को हल किया। मैं टिफ़ फ़ाइलों के एक फ़ोल्डर को संसाधित करना चाहता था, उन्हें बाइट में परिवर्तित करता था [] धाराएँ और एक सेवा को भेजता हूं, और फिर टिफ़ फ़ाइलों के फ़ोल्डर को "प्रोसेस" संग्रह फ़ोल्डर में ले जाता हूं। Image.FromFile टिफ़ फ़ाइल पर एक लॉक लगाती है, और इसे समय पर जारी नहीं करती है, इसलिए जब मैं टिफ़ फ़ाइलों और फ़ोल्डर को स्थानांतरित करने के लिए गया, तो मुझे "अन्य प्रक्रिया द्वारा उपयोग किया जा रहा" त्रुटि मिलेगी, क्योंकि ताले अभी भी थे जगह में। कर रहे हैं। टिफ़ फ़ाइल के बाइट्स प्राप्त करने के बाद सही करें। इस लॉक की गई फ़ाइल की समस्या को पूरी तरह से ठीक कर दें।
डेवलपर

4

मुझे यह त्रुटि मिली क्योंकि मैं File.Move एक फ़ाइल पथ पर एक फ़ाइल नाम के बिना कर रहा था, गंतव्य में पूर्ण पथ निर्दिष्ट करने की आवश्यकता है।


और न केवल एक फ़ाइल नाम के बिना। एक अवैध (गंतव्य) फ़ाइल नाम - मेरे मामले में "... \" फ़ाइल। " - यह वही बेवकूफ त्रुटि देगा और आपको आधे दिन के लिए गलत दिशा में इंगित करेगा!
निक वेस्टगेट

3

त्रुटि इंगित करती है कि एक और प्रक्रिया फ़ाइल तक पहुंचने की कोशिश कर रही है। हो सकता है कि जब आप इसे लिखने का प्रयास कर रहे हों तो आपके या किसी और के पास खुला हो। "पढ़ें या" कॉपी करें "आमतौर पर इसका कारण नहीं बनता है, लेकिन इसे लिखना या उस पर कॉल हटाना होगा।

इससे बचने के लिए कुछ बुनियादी बातें हैं, जैसा कि अन्य उत्तरों में उल्लेख किया गया है:

  1. में FileStreamआपरेशन, एक में रख usingएक साथ ब्लॉक FileShare.ReadWriteपहुँच के मोड।

    उदाहरण के लिए:

    using (FileStream stream = File.Open(path, FileMode.Open, FileAccess.Write, FileShare.ReadWrite))
    {
    }

    ध्यान दें कि FileAccess.ReadWriteयदि आप उपयोग करते हैं तो यह संभव नहीं है FileMode.Append

  2. जब मैं एक इनपुट स्ट्रीम का उपयोग कर रहा था, File.SaveAsजब फ़ाइल का उपयोग हो रहा था, तो मैं इस मुद्दे पर भागा । मेरे मामले में मैंने पाया, मुझे वास्तव में इसे फाइल सिस्टम में वापस सहेजने की आवश्यकता नहीं थी, इसलिए मैंने बस इसे हटा दिया, लेकिन मैंने शायद एक usingबयान में एक फाइलस्ट्रीम बनाने की कोशिश की FileAccess.ReadWrite, जैसे कोड। ऊपर।

  3. एक अलग फ़ाइल के रूप में अपने डेटा को सहेजना और पुराने को हटाने के लिए वापस जाना जब यह अब उपयोग में नहीं पाया जाता है, तो मूल नाम के लिए सफलतापूर्वक सहेजे गए का नाम बदलना एक विकल्प है। आप किस फ़ाइल का उपयोग कर रहे हैं, इसके माध्यम से पूरा किया जाता है

    List<Process> lstProcs = ProcessHandler.WhoIsLocking(file);

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

  4. जब आप यह नहीं जानते कि क्या कोई फ़ाइल उपयोग में होगी जब आप उसे सहेजने का प्रयास कर रहे हैं, तो आप सभी प्रक्रियाओं को बंद कर सकते हैं जो इसका उपयोग कर सकते हैं, जैसे Word, यदि यह Word दस्तावेज़ है, तो सहेजने से पहले।

    यदि यह स्थानीय है, तो आप यह कर सकते हैं:

    ProcessHandler.localProcessKill("winword.exe");

    यदि यह दूरस्थ है, तो आप यह कर सकते हैं:

    ProcessHandler.remoteProcessKill(computerName, txtUserName, txtPassword, "winword.exe");

    जहां txtUserNameके रूप में है DOMAIN\user

  5. मान लीजिए कि आप उस प्रक्रिया का नाम नहीं जानते हैं जो फ़ाइल को लॉक कर रही है। फिर, आप यह कर सकते हैं:

    List<Process> lstProcs = new List<Process>();
    lstProcs = ProcessHandler.WhoIsLocking(file);
    
    foreach (Process p in lstProcs)
    {
        if (p.MachineName == ".")
            ProcessHandler.localProcessKill(p.ProcessName);
        else
            ProcessHandler.remoteProcessKill(p.MachineName, txtUserName, txtPassword, p.ProcessName);
    }

    ध्यान दें कि fileयूएनसी पथ होना चाहिए: \\computer\share\yourdoc.docxक्रम में के लिए Processक्या कंप्यूटर पर वह है, यह पता लगाने के लिए और p.MachineNameवैध था।

    नीचे इन कार्यों का उपयोग करने वाला वर्ग है, जिसके लिए एक संदर्भ जोड़ने की आवश्यकता है System.Management। कोड मूल रूप से एरिक जे द्वारा लिखा गया था :

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Runtime.InteropServices;
    using System.Diagnostics;
    using System.Management;
    
    namespace MyProject
    {
        public static class ProcessHandler
        {
            [StructLayout(LayoutKind.Sequential)]
            struct RM_UNIQUE_PROCESS
            {
                public int dwProcessId;
                public System.Runtime.InteropServices.ComTypes.FILETIME ProcessStartTime;
            }
    
            const int RmRebootReasonNone = 0;
            const int CCH_RM_MAX_APP_NAME = 255;
            const int CCH_RM_MAX_SVC_NAME = 63;
    
            enum RM_APP_TYPE
            {
                RmUnknownApp = 0,
                RmMainWindow = 1,
                RmOtherWindow = 2,
                RmService = 3,
                RmExplorer = 4,
                RmConsole = 5,
                RmCritical = 1000
            }
    
            [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
            struct RM_PROCESS_INFO
            {
                public RM_UNIQUE_PROCESS Process;
    
                [MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCH_RM_MAX_APP_NAME + 1)]
                public string strAppName;
    
                [MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCH_RM_MAX_SVC_NAME + 1)]
                public string strServiceShortName;
    
                public RM_APP_TYPE ApplicationType;
                public uint AppStatus;
                public uint TSSessionId;
                [MarshalAs(UnmanagedType.Bool)]
                public bool bRestartable;
            }
    
            [DllImport("rstrtmgr.dll", CharSet = CharSet.Unicode)]
            static extern int RmRegisterResources(uint pSessionHandle,
                                                UInt32 nFiles,
                                                string[] rgsFilenames,
                                                UInt32 nApplications,
                                                [In] RM_UNIQUE_PROCESS[] rgApplications,
                                                UInt32 nServices,
                                                string[] rgsServiceNames);
    
            [DllImport("rstrtmgr.dll", CharSet = CharSet.Auto)]
            static extern int RmStartSession(out uint pSessionHandle, int dwSessionFlags, string strSessionKey);
    
            [DllImport("rstrtmgr.dll")]
            static extern int RmEndSession(uint pSessionHandle);
    
            [DllImport("rstrtmgr.dll")]
            static extern int RmGetList(uint dwSessionHandle,
                                        out uint pnProcInfoNeeded,
                                        ref uint pnProcInfo,
                                        [In, Out] RM_PROCESS_INFO[] rgAffectedApps,
                                        ref uint lpdwRebootReasons);
    
            /// <summary>
            /// Find out what process(es) have a lock on the specified file.
            /// </summary>
            /// <param name="path">Path of the file.</param>
            /// <returns>Processes locking the file</returns>
            /// <remarks>See also:
            /// http://msdn.microsoft.com/en-us/library/windows/desktop/aa373661(v=vs.85).aspx
            /// http://wyupdate.googlecode.com/svn-history/r401/trunk/frmFilesInUse.cs (no copyright in code at time of viewing)
            /// 
            /// </remarks>
            static public List<Process> WhoIsLocking(string path)
            {
                uint handle;
                string key = Guid.NewGuid().ToString();
                List<Process> processes = new List<Process>();
    
                int res = RmStartSession(out handle, 0, key);
                if (res != 0) throw new Exception("Could not begin restart session.  Unable to determine file locker.");
    
                try
                {
                    const int ERROR_MORE_DATA = 234;
                    uint pnProcInfoNeeded = 0,
                        pnProcInfo = 0,
                        lpdwRebootReasons = RmRebootReasonNone;
    
                    string[] resources = new string[] { path }; // Just checking on one resource.
    
                    res = RmRegisterResources(handle, (uint)resources.Length, resources, 0, null, 0, null);
    
                    if (res != 0) throw new Exception("Could not register resource.");
    
                    //Note: there's a race condition here -- the first call to RmGetList() returns
                    //      the total number of process. However, when we call RmGetList() again to get
                    //      the actual processes this number may have increased.
                    res = RmGetList(handle, out pnProcInfoNeeded, ref pnProcInfo, null, ref lpdwRebootReasons);
    
                    if (res == ERROR_MORE_DATA)
                    {
                        // Create an array to store the process results
                        RM_PROCESS_INFO[] processInfo = new RM_PROCESS_INFO[pnProcInfoNeeded];
                        pnProcInfo = pnProcInfoNeeded;
    
                        // Get the list
                        res = RmGetList(handle, out pnProcInfoNeeded, ref pnProcInfo, processInfo, ref lpdwRebootReasons);
                        if (res == 0)
                        {
                            processes = new List<Process>((int)pnProcInfo);
    
                            // Enumerate all of the results and add them to the 
                            // list to be returned
                            for (int i = 0; i < pnProcInfo; i++)
                            {
                                try
                                {
                                    processes.Add(Process.GetProcessById(processInfo[i].Process.dwProcessId));
                                }
                                // catch the error -- in case the process is no longer running
                                catch (ArgumentException) { }
                            }
                        }
                        else throw new Exception("Could not list processes locking resource.");
                    }
                    else if (res != 0) throw new Exception("Could not list processes locking resource. Failed to get size of result.");
                }
                finally
                {
                    RmEndSession(handle);
                }
    
                return processes;
            }
    
            public static void remoteProcessKill(string computerName, string userName, string pword, string processName)
            {
                var connectoptions = new ConnectionOptions();
                connectoptions.Username = userName;
                connectoptions.Password = pword;
    
                ManagementScope scope = new ManagementScope(@"\\" + computerName + @"\root\cimv2", connectoptions);
    
                // WMI query
                var query = new SelectQuery("select * from Win32_process where name = '" + processName + "'");
    
                using (var searcher = new ManagementObjectSearcher(scope, query))
                {
                    foreach (ManagementObject process in searcher.Get()) 
                    {
                        process.InvokeMethod("Terminate", null);
                        process.Dispose();
                    }
                }            
            }
    
            public static void localProcessKill(string processName)
            {
                foreach (Process p in Process.GetProcessesByName(processName))
                {
                    p.Kill();
                }
            }
    
            [DllImport("kernel32.dll")]
            public static extern bool MoveFileEx(string lpExistingFileName, string lpNewFileName, int dwFlags);
    
            public const int MOVEFILE_DELAY_UNTIL_REBOOT = 0x4;
    
        }
    }

2

जैसा कि इस थ्रेड के अन्य उत्तरों ने बताया है, इस त्रुटि को हल करने के लिए आपको कोड का सावधानीपूर्वक निरीक्षण करने की आवश्यकता है, यह समझने के लिए कि फ़ाइल कहाँ लॉक हो रही है।

मेरे मामले में, मैं मूव ऑपरेशन करने से पहले फाइल को ईमेल अटैचमेंट के रूप में भेज रहा था।

जब तक SMTP क्लाइंट ने ईमेल भेजना समाप्त नहीं किया तब तक फ़ाइल कुछ सेकंड के लिए लॉक हो गई।

मैंने जो समाधान अपनाया वह पहले फ़ाइल को स्थानांतरित करने के लिए था , और फिर ईमेल भेजें। इससे मेरे लिए समस्या हल हो गई।

एक अन्य संभावित समाधान, जैसा कि हडसन ने पहले बताया था, उपयोग के बाद वस्तु को निपटाना होगा।

public static SendEmail()
{
           MailMessage mMailMessage = new MailMessage();
           //setup other email stuff

            if (File.Exists(attachmentPath))
            {
                Attachment attachment = new Attachment(attachmentPath);
                mMailMessage.Attachments.Add(attachment);
                attachment.Dispose(); //disposing the Attachment object
            }
} 

यदि कोई फ़ाइल उपयोग File.Move()में है तो काम नहीं करेगा और वही त्रुटि देगा। अगर बस एक ई-मेल में एक फ़ाइल जोड़ रहा हूं, तो मुझे नहीं लगता कि यह Attachments.Add()ऑपरेशन के दौरान उपयोग में त्रुटियां हैं क्योंकि यह सिर्फ एक कॉपी ऑपरेशन है। यदि यह किसी कारण से किया गया है तो आप इसे एक Temp निर्देशिका में कॉपी कर सकते हैं, कॉपी संलग्न कर सकते हैं, और बाद में कॉपी की गई फ़ाइल को हटा सकते हैं। लेकिन मुझे नहीं लगता, अगर ओपी एक फाइल को संशोधित करना चाहता है और इसका उपयोग करता है, तो इस तरह का समाधान (जिसे आपने कोड नहीं दिखाया, केवल संलग्न भाग) काम करेगा। .Dispose()हमेशा एक अच्छा विचार है, लेकिन यहां प्रासंगिक नहीं है जब तक कि फ़ाइल एक पूर्व ऑप में नहीं खोली जाती।
vapcguy 17

1

मेरे पास निम्न परिदृश्य था जो समान त्रुटि पैदा कर रहा था:

  • सर्वर पर फ़ाइलें अपलोड करें
  • अपलोड होने के बाद पुरानी फ़ाइलों से छुटकारा पाएं

अधिकांश फाइलें आकार में छोटी थीं, हालाँकि, कुछ बड़ी थीं, और इसलिए उन्हें हटाने का प्रयास फ़ाइल तक नहीं पहुंच सका त्रुटि ।

यह खोजना आसान नहीं था, हालांकि, समाधान "निष्पादन को पूरा करने के लिए कार्य की प्रतीक्षा में " जितना आसान था।

using (var wc = new WebClient())
{
   var tskResult = wc.UploadFileTaskAsync(_address, _fileName);
   tskResult.Wait(); 
}

-1

मेरा नीचे वाला कोड इस समस्या को हल करता है, लेकिन मेरा सुझाव है कि सबसे पहले आपको यह समझने की आवश्यकता है कि इस समस्या का कारण क्या है और समाधान का प्रयास करें जिसे आप कोड द्वारा पा सकते हैं

मैं इस मुद्दे को हल करने के लिए एक और तरीका दे सकता हूं लेकिन बेहतर समाधान यह है कि आप अपनी कोडिंग संरचना की जांच करें और यह विश्लेषण करने का प्रयास करें कि यह क्या होता है, अगर आपको कोई समाधान नहीं मिला तो आप नीचे दिए गए इस कोड के साथ जा सकते हैं

try{
Start:
///Put your file access code here


}catch (Exception ex)
 {
//by anyway you need to handle this error with below code
   if (ex.Message.StartsWith("The process cannot access the file"))
    {
         //Wait for 5 seconds to free that file and then start execution again
         Thread.Sleep(5000);
         goto Start;
    }
 }

1
इस कोड के साथ कुछ समस्याएं: 1) यदि आपको कॉल करने की आवश्यकता है GC.*()तो आपके पास संभवतः आपके कोड के साथ अन्य समस्याएं हैं। 2) संदेश स्थानीयकृत और नाजुक है , इसके बजाय HRESULT का उपयोग करें। 3) आप के साथ सोना चाहते हो सकता है Task.Delay()(और दस सेकंड किसी तरह कई मामलों में अत्यधिक है)। 4) आपके पास बाहर निकलने की स्थिति नहीं है: यह कोड फोर्वर को लटका सकता है। 5) आपको निश्चित रूप से gotoयहां की जरूरत नहीं है। 6) पकड़ने के Exceptionलिए आमतौर पर एक बुरा विचार है, इस मामले में भी क्योंकि ... 6) अगर कुछ और होता है तो आप त्रुटि को निगल रहे हैं।
एड्रियानो रेपेती

@ AdrianoRepetti मेरी पहली टिप्पणी में कहा गया है कि इस कोड का उपयोग न करें अन्य समाधान खोजने की कोशिश करें यह अंतिम विकल्प होगा और किसी भी तरह से अगर यह त्रुटि होती है तो कोड बंद हो जाता है लेकिन अगर आप इस त्रुटि को संभाल रहे हैं तो फ़ाइल को मुक्त करने के लिए इंतजार करना होगा और उसके बाद यह शुरू होगा काम करना और मुझे GC के साथ अन्य मुद्दों का सामना नहीं करना पड़ता है। * इस कोड का उपयोग करते समय। मेरे पास पहले से ही इस कोड के साथ काम करने की प्रणाली है, इसलिए मैं किसी के लिए सहायक हो सकता है।
ऐश

मैं कभी भी इस कोड का उपयोग नहीं करने के लिए कहूंगा (ऊपर जिन बिंदुओं का मैंने उल्लेख किया है) और मैं इस पर काम करने वाले सिस्टम में काम नहीं करूंगा, लेकिन यह सिर्फ मेरा पीओवी है। असहमति महसूस करो!
एड्रियानो रेपेती

1) मैंने विंडोज़ सेवा का उपयोग किया, जहां मैंने इसका सेवन किया और मैंने GC का उपयोग किया। * इस तक मैं इस 2 के साथ किसी भी मुद्दे का सामना नहीं करता है) हाँ HRESULT मानक 3 को कोड करने के मामले में बेहतर विकल्प हो सकता है) उस स्थिति पर निर्भर करें जिस पर आप समय दे सकते हैं यह 5 सेकंड 4) किसी भी तरह से सिस्टम के लिए बेहतर है कि कुछ समय के लिए फ्री रिसोर्स पर रुकें, बजाय सिस्टम को एरर 5 के साथ रोकने के लिए) हां मैं आपसे सहमत हूं अपवाद अपवाद हैंडलिंग हमेशा अच्छा विचार नहीं है लेकिन अगर आपका कोड स्निपेट छोटा है और आप जानते हैं यहाँ मैं अपवाद को संभाल सकता हूँ तो यह समाधान आपके लिए एक विकल्प है।
ऐश

यह भी देखें: docs.microsoft.com/en-us/archive/blogs/ricom/... । केवल (और मैं केवल तनाव) मामले में मुझे GC.Collect()कुछ COM वस्तुओं के साथ काम करते समय उपयोग करने की आवश्यकता होती है ।
एड्रियानो रेपेती
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.