2010-11-05 10 views
6

में खोलें है मान लिया जाये कि मैं की तरह एक फ़ोल्डर संरचना है:DirectoryInfo.Delete (सच) नहीं हटाता है जब फ़ोल्डर संरचना Windows Explorer

Dim path As String = "C:\MyTemp" 
Dim di As System.IO.DirectoryInfo 
di = System.IO.Directory.CreateDirectory(path) 
di.CreateSubdirectory("MySubFolder") 
di.Delete(True) 
:

C:\MyTemp 
    - MySubFolder

अगर मैं इस का उपयोग कर हटाने का प्रयास

यह ठीक काम करता है, जब तक कि मेरे पास विंडोज एक्सप्लोरर खुला नहीं है और मैं 'MySubFolder' निर्देशिका देख रहा हूं। तब मुझे एक IOException मिलता है निर्देशिका खाली नहीं है। - ठीक क्लिक करके इसे खारिज कर दिया जाता है और फिर फ़ोल्डर संरचना हटाई नहीं जाती है।

विंडोज एक्सप्लोरर में फ़ोल्डर स्ट्रक्चर खोलने के दौरान भी इस कोड को चलाने के दौरान, मैं सही तरीके से प्रदर्शन करने के लिए इसे कैसे प्राप्त कर सकता हूं (यानी हटाएं)।

+4

ध्यान दें कि यह खोल का मानक व्यवहार है। आपको 'rmdir/S' से एक ही त्रुटि संदेश मिलेगा। मुझे लगता है कि विलोपन मूल रूप से विफल रहता है क्योंकि एक्सप्लोरर के पास अभी भी उपफोल्डर के लिए एक हैंडल है। –

+0

@ 0xA3 - यह संगत नहीं है। नीचे दिए गए उत्तर पर मेरी टिप्पणी देखें। ऐसे मामले हैं जहां मैं विंडोज एक्सप्लोरर में इसे देखते हुए फ़ोल्डर को हटा सकता हूं और फिर एक्सप्लोरर सिर्फ हटाए गए बच्चे के मूल फ़ोल्डर में जाता है। –

+0

@ToddMain मुझे पता है कि यह पुराना है लेकिन अगर आप इसके लिए समाधान पोस्ट कर सकते हैं तो मैं वास्तव में सराहना करूंगा। –

उत्तर

1

यह article देखें। IOException निर्देशिका में खुले हैंडल से उत्पन्न किया जा सकता है: This open handle can result from enumerating directories and files जो एक्सप्लोरर में बिल्कुल खुलता है। वास्तविक त्रुटि संदेश की तरह लगता है सामान्य है।

+0

हाँ, मैंने इसे पढ़ा था, लेकिन यह कहता है कि यह केवल WinXP और पहले लागू होता है।दूसरी बात, एक * MySubfolder * के तहत मान लें * मेरे पास "टेम्प" नामक एक और उपफोल्डर है और इसमें एक फ़ाइल "mypic.jpg" है। यदि मैं विंडोज एक्सप्लोरर में "टेम्प" फ़ोल्डर देख रहा हूं और ऊपर दिए गए कोड का उपयोग करके इसे (और jpg) हटा देता हूं, तो यह हटा देता है। यह असंगत रहा है और मुझे यकीन नहीं है कि इसके बारे में क्या करना है। –

2

केवल जिस तरह से आप "काम" को यह मिल सकता है 100% लगातार एक्सप्लोरर (बुरा विचार) nuking या हैंडल (also bad idea)

nuking के द्वारा होता है

मेरे सिफारिश सिर्फ शान से विफलता को संभालने के लिए होगा के रूप में की कोशिश कर रहा करने के लिए विरोध इस।

1

सबसे अच्छा तुम कर सकते त्रुटि को पकड़ और फिर handle.exe प्रयोग यह पता लगाने जो प्रक्रिया फ़ाइल का उपयोग और पुन: प्रयास करने के लिए या रद्द विकल्पों के साथ अनुप्रयोग को बंद करने के लिए उपयोगकर्ता पूछने के लिए है।

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

कुछ और यहाँ की जानकारी:

How to monitor process' IO activity using C#?

0

मैं निम्नलिखित DirectoryInfo विस्तार विधि है जो देशी DirectoryInfo.Delete() विधि लपेटता है और निर्दिष्ट फ़ोल्डर "सुरक्षित रूप से हटाएँ" करने का प्रयास के साथ आया था:

इस विधि निम्नलिखित COM संदर्भ की आवश्यकता है: माइक्रोसॉफ्ट इंटरनेट को नियंत्रित करता है COM Reference: Microsoft Internet Controls एक्स


    '''' <summary> 
    '''' Attempts to perform a "Safe delete" by searching for any Windows File Explorer instances attached to the extended DirectoryInfo Object 
    '''' and navigate those instances off the current DirectoryInfo path in an attempt to prevent a "Directory is not empty" IOException when 
    '''' calling DirectoryInfo.Delete(recursive). 
    '''' </summary> 
    '''' <param name="DirectoryInfo">The DirectoryInfo object being extended</param> 
    '''' <param name="recursive">Optional: true to delete this directory, its subdirectories, and all files; otherwise false</param> 
    '''' <returns>A Boolean indicating whether the DirectoryInfo.Delete(recursive) operation completed without an Exception</returns> 
    '''' <remarks>Authored by CMC 2013-05-06 12:04:25 PM</remarks> 
    <System.Runtime.CompilerServices.Extension()> _ 
    Public Function TrySafeDelete(ByVal [DirectoryInfo] As DirectoryInfo, Optional ByVal recursive As Boolean = False, Optional ByVal retryCount As Integer = 0) As Boolean 
     Const maxRetryCount As Integer = 10 
     retryCount = If(retryCount < 0, 0, retryCount) 
     Dim success As Boolean = True 
     If ([DirectoryInfo] IsNot Nothing) Then 
      [DirectoryInfo].Refresh() 
      Dim msWinShellIExplorerWindowsLockingCurrentDirectory As Dictionary(Of SHDocVw.InternetExplorer, DirectoryInfo) = New Dictionary(Of SHDocVw.InternetExplorer, DirectoryInfo) 
      If ([DirectoryInfo].Exists()) Then 
       Try 
        Dim msWinShellIExplorerWindows As SHDocVw.ShellWindows = New SHDocVw.ShellWindows() 
        For Each msWinShellIExplorerWindow As SHDocVw.InternetExplorer In msWinShellIExplorerWindows 
         If (msWinShellIExplorerWindow.Name.Equals("windows explorer", StringComparison.OrdinalIgnoreCase)) Then 
          Dim locationValue As String = msWinShellIExplorerWindow.LocationURL() 
          If (locationValue.Length() > 0) Then 
           Dim locationURI As Uri = Nothing 
           If (Uri.TryCreate(locationValue, UriKind.RelativeOrAbsolute, locationURI)) Then 
            Dim msWinShellDirectoryInfo As DirectoryInfo = New DirectoryInfo(locationURI.LocalPath()) 
            Dim isLockingCurrentDirectory As Boolean = msWinShellDirectoryInfo.FullName.ToLower().Contains([DirectoryInfo].FullName.ToLower()) 
            If (isLockingCurrentDirectory AndAlso Not msWinShellIExplorerWindowsLockingCurrentDirectory.ContainsKey(msWinShellIExplorerWindow)) Then msWinShellIExplorerWindowsLockingCurrentDirectory.Add(msWinShellIExplorerWindow, msWinShellDirectoryInfo) 
           End If 
          End If 
         End If 
        Next 

        Dim navigateCompleteCount As Integer = 0 
        If (msWinShellIExplorerWindowsLockingCurrentDirectory.Any()) Then 
         For Each msWinShellDirectoryEntry As KeyValuePair(Of SHDocVw.InternetExplorer, DirectoryInfo) In msWinShellIExplorerWindowsLockingCurrentDirectory 
          Dim msWinShellIExplorerWindow As SHDocVw.InternetExplorer = msWinShellDirectoryEntry.Key() 
          Dim msWinShellDirectoryInfo As DirectoryInfo = msWinShellDirectoryEntry.Value() 
          AddHandler msWinShellIExplorerWindow.NavigateComplete2, New SHDocVw.DWebBrowserEvents2_NavigateComplete2EventHandler(Sub(pDisp As Object, ByRef URL As Object) 
                                        navigateCompleteCount += 1 
                                        If (navigateCompleteCount.Equals(msWinShellIExplorerWindowsLockingCurrentDirectory.Count())) Then 
                                         With [DirectoryInfo] 
                                          .Delete(recursive) 
                                          .Refresh() 
                                         End With 
                                        End If 
                                       End Sub) 
          msWinShellIExplorerWindow.Navigate2(New Uri(msWinShellDirectoryInfo.Root.FullName()).AbsoluteUri()) 
         Next 
        Else 
         With [DirectoryInfo] 
          .Delete(recursive) 
          .Refresh() 
         End With 
        End If 
       Catch ex As Exception 
       End Try 

       [DirectoryInfo].Refresh() 
       If ([DirectoryInfo].Exists() AndAlso (retryCount <= maxRetryCount)) Then 
        [DirectoryInfo].TrySafeDelete(recursive, retryCount + 1) 
       End If 
       success = Not DirectoryInfo.Exists() 
      End If 
     End If 
     Return success 
    End Function 
संबंधित मुद्दे