1
1
using SecureFolderFS . Core . FileSystem ;
2
2
using SecureFolderFS . Core . FileSystem . Enums ;
3
+ using SecureFolderFS . Core . FileSystem . Helpers ;
4
+ using SecureFolderFS . Core . WebDav . UnsafeNative ;
3
5
using SecureFolderFS . Sdk . Storage ;
6
+ using System ;
7
+ using System . IO ;
4
8
using System . Threading . Tasks ;
5
9
6
10
namespace SecureFolderFS . Core . WebDav
@@ -28,7 +32,16 @@ public WebDavFileSystem(IFolder rootFolder, WebDavWrapper webDavWrapper)
28
32
public async Task < bool > CloseAsync ( FileSystemCloseMethod closeMethod )
29
33
{
30
34
if ( IsOperational )
31
- IsOperational = ! await Task . Run ( ( ) => _webDavWrapper . CloseFileSystem ( closeMethod ) ) ;
35
+ {
36
+ var closeResult = ! await Task . Run ( ( ) => _webDavWrapper . CloseFileSystem ( closeMethod ) ) ;
37
+ IsOperational = ! closeResult ;
38
+
39
+ if ( closeResult && OperatingSystem . IsWindows ( ) ) // Closed successfully
40
+ {
41
+ // Close all file explorer windows
42
+ await CloseExplorerShellAsync ( RootFolder . Id ) ;
43
+ }
44
+ }
32
45
33
46
return ! IsOperational ;
34
47
}
@@ -38,5 +51,57 @@ public async ValueTask DisposeAsync()
38
51
{
39
52
_ = await CloseAsync ( FileSystemCloseMethod . CloseForcefully ) ;
40
53
}
54
+
55
+ private static async Task CloseExplorerShellAsync ( string path )
56
+ {
57
+ var formattedPath = PathHelpers . EnsureNoTrailingPathSeparator ( path ) ;
58
+ var shellWindows = new SHDocVw . ShellWindows ( ) ;
59
+
60
+ foreach ( SHDocVw . InternetExplorer ie in shellWindows )
61
+ {
62
+ var formattedName = Path . GetFileNameWithoutExtension ( ie . FullName ) ;
63
+ if ( ! formattedName . Equals ( "explorer" , StringComparison . OrdinalIgnoreCase ) )
64
+ continue ;
65
+
66
+ var url = ie . LocationURL . Replace ( '/' , Path . DirectorySeparatorChar ) ;
67
+ var formattedUrl = Uri . UnescapeDataString ( url ) ;
68
+ if ( ! formattedUrl . Contains ( formattedPath ) )
69
+ continue ;
70
+
71
+ var windowClosed = false ;
72
+ try
73
+ {
74
+ // Hook up closing event
75
+ ie . WindowClosing += Window_Closing ;
76
+
77
+ // Try quit first
78
+ ie . Quit ( ) ;
79
+
80
+ // Wait a short delay
81
+ await Task . Delay ( 100 ) ;
82
+
83
+ if ( ! windowClosed )
84
+ {
85
+ // Retry with WM_CLOSE
86
+ _ = UnsafeNativeApis . SendMessageA ( ie . HWND , WindowMessages . WM_CLOSE , IntPtr . Zero , IntPtr . Zero ) ;
87
+ }
88
+ }
89
+ catch ( Exception ex )
90
+ {
91
+ // May sometimes throw when trying to access invalid window handle
92
+ _ = ex ;
93
+ }
94
+ finally
95
+ {
96
+ // Unhook to avoid leaking memory
97
+ ie . WindowClosing -= Window_Closing ;
98
+ }
99
+
100
+ void Window_Closing ( bool IsChildWindow , ref bool Cancel )
101
+ {
102
+ windowClosed = true ;
103
+ }
104
+ }
105
+ }
41
106
}
42
107
}
0 commit comments