diff --git a/ExplorerTabUtility/App.config b/ExplorerTabUtility/App.config
index c5108bd..b42d465 100644
--- a/ExplorerTabUtility/App.config
+++ b/ExplorerTabUtility/App.config
@@ -11,7 +11,7 @@
True
- False
+ True
diff --git a/ExplorerTabUtility/ExplorerTabUtility.csproj b/ExplorerTabUtility/ExplorerTabUtility.csproj
index c595aeb..7466ea0 100644
--- a/ExplorerTabUtility/ExplorerTabUtility.csproj
+++ b/ExplorerTabUtility/ExplorerTabUtility.csproj
@@ -7,6 +7,8 @@
true
True
Icon.ico
+ 1.1.0
+ latest
Explorer Tab Utility
w4po
$(AssemblyName)
diff --git a/ExplorerTabUtility/Forms/TrayIcon.cs b/ExplorerTabUtility/Forms/TrayIcon.cs
index 17912b2..17eafbb 100644
--- a/ExplorerTabUtility/Forms/TrayIcon.cs
+++ b/ExplorerTabUtility/Forms/TrayIcon.cs
@@ -145,9 +145,8 @@ private static async Task OnNewWindow(Window window)
UiAutomation.AddNewTab(windowElement);
- // If it is just a new (This PC) window, return.
+ // If it is just a new (This PC | Home), return.
if (string.IsNullOrWhiteSpace(window.Path)) return;
- if (!Uri.TryCreate(window.Path, UriKind.Absolute, out var uri)) return;
var newTabHandle = WinApi.ListenForNewExplorerTab(oldTabs);
if (newTabHandle == default) return;
@@ -155,7 +154,7 @@ private static async Task OnNewWindow(Window window)
var newTabElement = UiAutomation.FromHandle(newTabHandle);
if (newTabElement == default) return;
- UiAutomation.GoToLocation(uri.LocalPath, windowElement);
+ UiAutomation.GoToLocation(window.Path, windowElement);
if (window.SelectedItems is not { } selectedItems) return;
diff --git a/ExplorerTabUtility/Helpers/Helper.cs b/ExplorerTabUtility/Helpers/Helper.cs
index f793895..f48af9f 100644
--- a/ExplorerTabUtility/Helpers/Helper.cs
+++ b/ExplorerTabUtility/Helpers/Helper.cs
@@ -2,13 +2,25 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
-using System.IO;
using System.Threading;
namespace ExplorerTabUtility.Helpers;
public static class Helper
{
+ public static T DoUntilCondition(Func action, Predicate predicate, int timeMs = 500, CancellationToken cancellationToken = default)
+ {
+ var startTicks = Stopwatch.GetTimestamp();
+
+ while (!cancellationToken.IsCancellationRequested && !IsTimeUp(startTicks, timeMs))
+ {
+ var result = action.Invoke();
+ if (predicate(result))
+ return result;
+ }
+
+ return action.Invoke();
+ }
public static T DoUntilNotDefault(Func action, int timeMs = 500, CancellationToken cancellationToken = default)
{
var startTicks = Stopwatch.GetTimestamp();
@@ -59,21 +71,4 @@ public static TimeSpan GetElapsedTime(long startTicks)
return Icon.ExtractAssociatedIcon(location);
}
-
- public static string GetFullPath(string path)
- {
- // Check if the path contains environment variables
- if (path.StartsWith("%") && path.EndsWith("%"))
- {
- // Replace environment variables with their values
- path = Environment.ExpandEnvironmentVariables(path);
- }
-
- // If it has : or \, assume it's a regular path
- if (path.Contains(":") || path.Contains("\\")) return path;
-
- // Check if the path is a special folder
- var fullPath = $"{Environment.GetEnvironmentVariable("USERPROFILE")}\\{path}";
- return Directory.Exists(fullPath) ? fullPath : path;
- }
}
\ No newline at end of file
diff --git a/ExplorerTabUtility/Hooks/UiAutomation.cs b/ExplorerTabUtility/Hooks/UiAutomation.cs
index 1943e2f..94514d5 100644
--- a/ExplorerTabUtility/Hooks/UiAutomation.cs
+++ b/ExplorerTabUtility/Hooks/UiAutomation.cs
@@ -1,6 +1,5 @@
using System;
using System.Linq;
-using System.Threading;
using System.Threading.Tasks;
using System.Collections.Generic;
using FlaUI.Core.AutomationElements;
@@ -49,18 +48,15 @@ private void OnWindowOpened(AutomationElement element, EventId _)
if (_cache.Contains(hWnd)) return;
_cache.Add(hWnd);
- WinApi.GetWindowRect(hWnd, out var originalRect);
- // Move the window outside the screen (Hide)
- WinApi.SetWindowPos(hWnd, IntPtr.Zero, -1000, -1000, 0, 0, WinApi.SWP_NOSIZE | WinApi.SWP_NOZORDER);
+ var originalRect = HideWindow(hWnd);
var showAgain = true;
try
{
- // a new "This PC" window (unless the opened folder is called "This PC"?)
+ // A new "This PC" window (unless the opened folder is called "This PC"?)
if (string.Equals(element.Name, "This PC"))
{
- // the window suppose to have only one tab, so we should be okay.
- CloseRandomTabOfAWindow(element);
- _onNewWindow.Invoke(new Window(string.Empty));
+ CloseAndNotifyNewWindow(element, new Window(string.Empty, oldWindowHandle: hWnd));
+ showAgain = false;
return;
}
@@ -69,38 +65,47 @@ private void OnWindowOpened(AutomationElement element, EventId _)
// We have to invoke the suggestBox to populate the address bar :(
suggestBox.Patterns.Invoke.Pattern.Invoke();
- Thread.Sleep(50);
// Invoke searchBox to hide the suggestPopup window.
searchBox.Patterns.Invoke.Pattern.Invoke();
- Thread.Sleep(50);
- var location = addressBar.Patterns.Value.Pattern.Value.Value;
+ var location = Helper.DoUntilCondition(
+ action: () => addressBar.Patterns.Value.Pattern.Value.Value,
+ predicate: l => !string.IsNullOrWhiteSpace(l));
if (string.IsNullOrWhiteSpace(location))
+ return;
+
+ // ("Home") For English version.
+ if (string.Equals(location, "Home"))
{
- // Hmm... Let's try one more time.
- Thread.Sleep(300);
- location = addressBar.Patterns.Value.Pattern.Value.Value;
- if (string.IsNullOrWhiteSpace(location)) return;
+ CloseAndNotifyNewWindow(element, new Window(string.Empty, oldWindowHandle: hWnd));
+ showAgain = false;
+ return;
}
- location = Helper.GetFullPath(location);
var tab = element.FindFirstChild(c => c.ByClassName("ShellTabWindowClass"));
var folderView = tab?.FindFirstDescendant(c => c.ByClassName("UIItemsView"));
- if (folderView == null) return;
+ if (folderView == default)
+ {
+ // ("Home") For non English versions.
+ var home = tab?.FindFirstDescendant(c => c.ByClassName("HomeListView"));
+ if (home == default) return;
- var selectedNames = folderView.Patterns.Selection.Pattern.Selection.Value?
- .Select(s => s.Name).ToList();
+ CloseAndNotifyNewWindow(element, new Window(string.Empty, oldWindowHandle: hWnd));
+ showAgain = false;
+ return;
+ }
+
+ var selectedNames = folderView.Patterns.Selection.Pattern.Selection.Value
+ ?.Select(s => s.Name)
+ .ToList();
var tabHWnd = tab!.Properties.NativeWindowHandle.Value;
- // the window suppose to have only one tab, so we should be okay.
- CloseRandomTabOfAWindow(element);
+ CloseAndNotifyNewWindow(element, new Window(location, selectedNames, hWnd, tabHWnd));
showAgain = false;
-
- _onNewWindow.Invoke(new Window(location, selectedNames, hWnd, tabHWnd));
}
finally
{
@@ -108,7 +113,6 @@ private void OnWindowOpened(AutomationElement element, EventId _)
if (showAgain)
WinApi.SetWindowPos(hWnd, IntPtr.Zero, originalRect.Left, originalRect.Top, 0, 0, WinApi.SWP_NOSIZE | WinApi.SWP_NOZORDER);
}
-
}
public static AutomationElement? FromHandle(IntPtr hWnd) => Automation.FromHandle(hWnd);
public static void AddNewTab(AutomationElement windowElement)
@@ -143,35 +147,18 @@ public static void GoToLocation(string location, AutomationElement windowElement
GetHeaderElements(windowElement, out var suggestBox, out var searchBox, out var addressBar);
if (suggestBox == default || searchBox == default || addressBar == default) return;
- // Set location
+ suggestBox.Patterns.Invoke.Pattern.Invoke();
addressBar.Patterns.Value.Pattern.SetValue(location);
// We have to invoke the suggestBox to Navigate :(
suggestBox.Patterns.Invoke.Pattern.Invoke();
- Thread.Sleep(50);
// Invoke searchBox to hide the suggestPopup window.
searchBox.Patterns.Invoke.Pattern.Invoke();
- var suggestList = Helper.DoUntilNotDefault(() => suggestBox.FindFirstChild("SuggestionsList"));
- if (suggestList != default)
- searchBox.Patterns.Invoke.Pattern.Invoke();
-
- //var startTime = Stopwatch.GetTimestamp();
- //while (Stopwatch.GetElapsedTime(startTime).TotalMilliseconds < 700)
- //{
- // var suggestList = suggestBox.FindFirstChild("SuggestionsList")?.FindAllChildren();
- // if (suggestList == default) continue;
-
- // foreach (var suggestItem in suggestList)
- // {
- // if (string.Equals(suggestItem.Name, location, StringComparison.OrdinalIgnoreCase))
- // {
- // suggestItem.Patterns.Invoke.Pattern.Invoke();
- // return;
- // }
- // }
- //}
+ //var suggestList = Helper.DoUntilNotDefault(() => suggestBox.FindFirstDescendant("SuggestionsList"));
+ //if (suggestList != default)
+ // searchBox.Patterns.Invoke.Pattern.Invoke();
}
public static void SelectItems(AutomationElement tabElement, ICollection names)
{
@@ -224,7 +211,20 @@ private static void GetHeaderElements(AutomationElement window, out AutomationEl
suggestBox = headerBar.FindFirstChild("PART_AutoSuggestBox");
addressBar = suggestBox?.FindFirstChild(c => c.ByName("Address Bar"));
}
+ private static RECT HideWindow(IntPtr hWnd)
+ {
+ WinApi.GetWindowRect(hWnd, out var originalRect);
+ // Move the window outside the screen (Hide)
+ WinApi.SetWindowPos(hWnd, IntPtr.Zero, -1000, -1000, 0, 0, WinApi.SWP_NOSIZE | WinApi.SWP_NOZORDER);
+ return originalRect;
+ }
+ private void CloseAndNotifyNewWindow(AutomationElement element, Window window)
+ {
+ // the window suppose to have only one tab, so we should be okay.
+ CloseRandomTabOfAWindow(element);
+ _onNewWindow.Invoke(window);
+ }
public void Dispose()
{
diff --git a/ExplorerTabUtility/Properties/Settings.Designer.cs b/ExplorerTabUtility/Properties/Settings.Designer.cs
index aa07df4..80852ad 100644
--- a/ExplorerTabUtility/Properties/Settings.Designer.cs
+++ b/ExplorerTabUtility/Properties/Settings.Designer.cs
@@ -37,7 +37,7 @@ public bool KeyboardHook {
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Configuration.DefaultSettingValueAttribute("False")]
+ [global::System.Configuration.DefaultSettingValueAttribute("True")]
public bool WindowHook {
get {
return ((bool)(this["WindowHook"]));
diff --git a/ExplorerTabUtility/Properties/Settings.settings b/ExplorerTabUtility/Properties/Settings.settings
index f3b9128..e73ce8e 100644
--- a/ExplorerTabUtility/Properties/Settings.settings
+++ b/ExplorerTabUtility/Properties/Settings.settings
@@ -6,7 +6,7 @@
True
- False
+ True
\ No newline at end of file