diff --git a/EverythingToolbar/Helpers/EverythingProcessHelper.cs b/EverythingToolbar/Helpers/EverythingProcessHelper.cs new file mode 100644 index 000000000..b6316d8d4 --- /dev/null +++ b/EverythingToolbar/Helpers/EverythingProcessHelper.cs @@ -0,0 +1,95 @@ +using System; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices; +using System.Threading; + +namespace EverythingToolbar.Helpers +{ + public static class EverythingProcessHelper + { + private const string Dll64 = "Everything64.dll"; + + [DllImport(Dll64, EntryPoint = "Everything_QueryW", CharSet = CharSet.Unicode)] + private static extern bool Everything64_QueryW(bool wait); + + [DllImport(Dll64, EntryPoint = "Everything_IsDBLoaded")] + private static extern bool Everything64_IsDBLoaded(); + + [DllImport(Dll64, EntryPoint = "Everything_GetLastError")] + private static extern uint Everything64_GetLastError(); + + /// + /// Checks if Everything is running and DB is loaded. + /// + public static bool IsRunning() + { + try + { + // Try a dummy query (empty string = no results) + if (!Everything64_QueryW(false)) + return false; + + return Everything64_IsDBLoaded(); + } + catch + { + return false; + } + } + + /// + /// Ensures Everything is running. + /// If not, starts Everything.exe in background with -startup. + /// Waits until DB is loaded or timeout expires. + /// + public static bool EnsureRunning(int timeoutMs = 5000) + { + if (IsRunning()) + { + return true; + } + + string[] possiblePaths = + { + ToolbarSettings.User.EverythingPath, + @"C:\Program Files\Everything\Everything.exe", + @"C:\Program Files (x86)\Everything\Everything.exe", + Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Everything\\Everything.exe"), + }; + + var everythingPath = possiblePaths.FirstOrDefault(p => File.Exists(p)); + if (everythingPath == null) + { + return false; + } + + try + { + Process.Start(new ProcessStartInfo + { + FileName = everythingPath, + Arguments = "-startup -first-instance", + UseShellExecute = false, + CreateNoWindow = true + }); + + var sw = Stopwatch.StartNew(); + while (sw.ElapsedMilliseconds < timeoutMs) + { + if (IsRunning()) + return true; + + Thread.Sleep(millisecondsTimeout: 10); + } + } + catch (Exception) + { + // don't block. User can start Everything on their own as well. + } + + return false; + } + } +} \ No newline at end of file diff --git a/EverythingToolbar/Search/SearchResultProvider.cs b/EverythingToolbar/Search/SearchResultProvider.cs index 4c22bef0d..26ae047b5 100644 --- a/EverythingToolbar/Search/SearchResultProvider.cs +++ b/EverythingToolbar/Search/SearchResultProvider.cs @@ -394,7 +394,7 @@ private static void LogLastError() } } - private static bool Initialize() + private bool Initialize() { SetInstanceName(ToolbarSettings.User.InstanceName); @@ -417,6 +417,7 @@ private static bool Initialize() { LogLastError(); Logger.Error("Failed to get Everything version number."); + this.IsBusy = true; } else { diff --git a/EverythingToolbar/SearchWindow.xaml.cs b/EverythingToolbar/SearchWindow.xaml.cs index fb04c80e3..dbe2c37d2 100644 --- a/EverythingToolbar/SearchWindow.xaml.cs +++ b/EverythingToolbar/SearchWindow.xaml.cs @@ -1,12 +1,13 @@ -using System; +using EverythingToolbar.Helpers; +using EverythingToolbar.Search; +using System; +using System.Threading; using System.Windows; using System.Windows.Input; using System.Windows.Interop; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Threading; -using EverythingToolbar.Helpers; -using EverythingToolbar.Search; namespace EverythingToolbar { @@ -29,6 +30,27 @@ private SearchWindow() private void OnActivated(object? sender, EventArgs e) { + // check if Everything.exe process is running or not. If it is not running then start it in background. + Dispatcher.BeginInvoke(new Action(() => + { + if (!EverythingProcessHelper.IsRunning()) + { + EverythingProcessHelper.EnsureRunning(); + + Dispatcher.Invoke(() => + { + // Triggers search again after the start of Everything process. + var textBox = (SearchBox.FindName("TextBox") as System.Windows.Controls.TextBox); + if (textBox != null) + { + textBox.Text = " "; + textBox.Text = ""; + } + }); + } + + }), DispatcherPriority.Background); + if (TaskbarStateManager.Instance.IsIcon) EventDispatcher.Instance.InvokeSearchBoxFocused(this, EventArgs.Empty); @@ -57,7 +79,7 @@ private void OnLostKeyboardFocus(object? sender, KeyboardFocusChangedEventArgs e { if (e.NewFocus == null) // New focus outside application { - Hide(); + Hide(); } }