DirectoryInfo.Delete (True) Does not delete when the folder structure is open in Windows Explorer

Assuming I have a folder structure like this:

  C: \ MyTemp
    - MySubFolder 

If I try to remove this using:

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

This works fine if I don't have Windows Explorer open and I look at the "MySubFolder" directory. Then I get an IOException. The directory is not empty. - pressing the “OK” button cancels this, and then the folder structure is not deleted.

Any thoughts on how I can get this to execute correctly (i.e. delete), even when I run this code when opening a folder in Windows Explorer?

+6
c # directoryinfo
source share
4 answers

Only in this way can you make it "work" 100% sequentially using a nuking explorer (bad idea) or a nuking descriptor ( also a bad idea )

My recommendation would be to simply handle the failure gracefully and not try to do it.

+2
source share

Check out this article. An IOException can be thrown from an open descriptor into a directory: This open handle can result from enumerating directories and files , which makes an opening in Explorer. It seems that the actual error message is general.

+1
source share

The best you can do is catch the error and then use handle.exe to find out which process is using the file, and ask to close the application using the options for retrying or canceling.

Have you ever wondered which program has a specific file or directory? Now you can find out. Handle is a utility that displays information about open descriptors for any process in the system. You can use it to view programs with an open file or to view the types of objects and the names of all the program descriptors.

Further information here:

How to track IO process activity using C #?

+1
source share

I came up with the following DirectoryInfo extension method, which wraps its own DirectoryInfo.Delete () method and tries to "safely delete" the specified folder:

This method requires the following COM link: Microsoft Internet Controls COM Reference: Microsoft Internet Controls x

 '''' <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 
0
source share

All Articles