-
Notifications
You must be signed in to change notification settings - Fork 6
File explorer support #27
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
6a67fd1
3cc47fe
95f0e1c
360aa1e
c6c05a6
6bd718d
1fcc0e7
858002c
3fd1fc3
c48ed99
a0f66e8
ccbbe45
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,91 @@ | ||
| using System; | ||
| using System.Collections.Generic; | ||
| using System.IO; | ||
| using System.Linq; | ||
| using System.Runtime.InteropServices; | ||
|
|
||
| namespace Wox.Plugin.Runner | ||
| { | ||
| class ExplorerPathsService | ||
| { | ||
| public static List<string> GetOpenExplorerPaths() | ||
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This uses the "Shell" to iterate over all file explorer windows and read the file paths and HWNDs from them. Finally, it combines that info to return a sorted list of open file explorer windows. This means that |
||
| { | ||
| Type? type = Type.GetTypeFromProgID("Shell.Application"); | ||
| if (type == null) return new List<string>(); | ||
| dynamic? shell = Activator.CreateInstance(type); | ||
| if (shell == null) return new List<string>(); | ||
| try | ||
| { | ||
| var fullResults = new List<ExplorerResult>(); | ||
|
|
||
| var openWindows = shell.Windows(); | ||
| for (int i = 0; i < openWindows.Count; i++) | ||
| { | ||
| var window = openWindows.Item(i); | ||
| if (window == null) continue; | ||
| var fileName = Path.GetFileName((string)window.FullName); | ||
|
|
||
| // Other things which are returned include the internet explorer and the classic control panel | ||
| // We only want file explorer windows | ||
| if (fileName.ToLower() == "explorer.exe") | ||
| { | ||
| string locationUrl = window.LocationURL; | ||
| if (!string.IsNullOrEmpty(locationUrl)) | ||
| { | ||
| fullResults.Add(new ExplorerResult(new IntPtr(window.HWND), new Uri(locationUrl).LocalPath)); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| int zIndex = fullResults.Count; | ||
| // EnumWindows iterates over windows in ZIndex order, basically the foremost window will be the first one | ||
| EnumWindows((IntPtr hwnd, IntPtr param) => | ||
| { | ||
| var result = fullResults.Find(v => v.HWND == hwnd); | ||
| if(result != null) | ||
| { | ||
| result.ZIndex = zIndex; | ||
| zIndex -= 1; | ||
| } | ||
| // zIndex is also used as a counter: how many more windows do we have to find | ||
| return zIndex > 0; | ||
| }, IntPtr.Zero); | ||
|
|
||
| // sort descending and return the paths | ||
| return fullResults | ||
| .OrderByDescending(v => v.ZIndex) | ||
| .Select(v => v.Path) | ||
| .ToList(); | ||
| } | ||
| finally | ||
| { | ||
| Marshal.FinalReleaseComObject(shell); | ||
| } | ||
| } | ||
|
|
||
| private class ExplorerResult | ||
| { | ||
| /// <summary> | ||
| /// Higher values means that the window is closer to the user | ||
| /// </summary> | ||
| public int ZIndex { get; set; } = 0; | ||
| public IntPtr HWND { get; } | ||
| public string Path { get; } | ||
|
|
||
| public ExplorerResult(IntPtr hwnd, string path) | ||
| { | ||
| HWND = hwnd; | ||
| Path = path; | ||
| } | ||
| } | ||
|
|
||
| [DllImport("user32.dll")] | ||
| [return: MarshalAs(UnmanagedType.Bool)] | ||
| private static extern bool EnumWindows(EnumWindowsProc enumProc, IntPtr lParam); | ||
|
|
||
| // Delegate to filter which windows to include | ||
| public delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam); | ||
|
|
||
|
|
||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Working directory can be set to
{explorer}, which will trigger the new behavior where it tries to get the path of the topmost file explorer window.