1
1
using System ;
2
+ using System . Collections . Generic ;
3
+ using System . IO ;
4
+ using System . Linq ;
5
+ using Windows . Win32 ;
2
6
3
7
namespace Flow . Launcher . Infrastructure
4
8
{
@@ -9,10 +13,9 @@ public static class FileExplorerHelper
9
13
/// </summary>
10
14
public static string GetActiveExplorerPath ( )
11
15
{
12
- var explorerPath = QuickSwitch . QuickSwitch . GetActiveExplorerPath ( ) ;
13
- return ! string . IsNullOrEmpty ( explorerPath ) ?
14
- GetDirectoryPath ( new Uri ( explorerPath ) . LocalPath ) :
15
- null ;
16
+ var explorerWindow = GetActiveExplorer ( ) ;
17
+ string locationUrl = explorerWindow ? . LocationURL ;
18
+ return ! string . IsNullOrEmpty ( locationUrl ) ? GetDirectoryPath ( new Uri ( locationUrl ) . LocalPath ) : null ;
16
19
}
17
20
18
21
/// <summary>
@@ -27,5 +30,67 @@ private static string GetDirectoryPath(string path)
27
30
28
31
return path ;
29
32
}
33
+
34
+ /// <summary>
35
+ /// Gets the file explorer that is currently in the foreground
36
+ /// </summary>
37
+ private static dynamic GetActiveExplorer ( )
38
+ {
39
+ Type type = Type . GetTypeFromProgID ( "Shell.Application" ) ;
40
+ if ( type == null ) return null ;
41
+ dynamic shell = Activator . CreateInstance ( type ) ;
42
+ if ( shell == null )
43
+ {
44
+ return null ;
45
+ }
46
+
47
+ var explorerWindows = new List < dynamic > ( ) ;
48
+ var openWindows = shell . Windows ( ) ;
49
+ for ( int i = 0 ; i < openWindows . Count ; i ++ )
50
+ {
51
+ var window = openWindows . Item ( i ) ;
52
+ if ( window == null ) continue ;
53
+
54
+ // find the desired window and make sure that it is indeed a file explorer
55
+ // we don't want the Internet Explorer or the classic control panel
56
+ // ToLower() is needed, because Windows can report the path as "C:\\Windows\\Explorer.EXE"
57
+ if ( Path . GetFileName ( ( string ) window . FullName ) ? . ToLower ( ) == "explorer.exe" )
58
+ {
59
+ explorerWindows . Add ( window ) ;
60
+ }
61
+ }
62
+
63
+ if ( explorerWindows . Count == 0 ) return null ;
64
+
65
+ var zOrders = GetZOrder ( explorerWindows ) ;
66
+
67
+ return explorerWindows . Zip ( zOrders ) . MinBy ( x => x . Second ) . First ;
68
+ }
69
+
70
+ /// <summary>
71
+ /// Gets the z-order for one or more windows atomically with respect to each other. In Windows, smaller z-order is higher. If the window is not top level, the z order is returned as -1.
72
+ /// </summary>
73
+ private static IEnumerable < int > GetZOrder ( List < dynamic > hWnds )
74
+ {
75
+ var z = new int [ hWnds . Count ] ;
76
+ for ( var i = 0 ; i < hWnds . Count ; i ++ ) z [ i ] = - 1 ;
77
+
78
+ var index = 0 ;
79
+ var numRemaining = hWnds . Count ;
80
+ PInvoke . EnumWindows ( ( wnd , _ ) =>
81
+ {
82
+ var searchIndex = hWnds . FindIndex ( x => new IntPtr ( x . HWND ) == wnd ) ;
83
+ if ( searchIndex != - 1 )
84
+ {
85
+ z [ searchIndex ] = index ;
86
+ numRemaining -- ;
87
+ if ( numRemaining == 0 ) return false ;
88
+ }
89
+ index ++ ;
90
+ return true ;
91
+ } , IntPtr . Zero ) ;
92
+
93
+ return z ;
94
+ }
30
95
}
31
96
}
0 commit comments