diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml index 22ab2016c..299fe3029 100644 --- a/Flow.Launcher/Languages/en.xaml +++ b/Flow.Launcher/Languages/en.xaml @@ -373,6 +373,8 @@ File Manager Path Arg For Folder Arg For File + The path for the file manager '{0}' could not be found: {1}\n\nDo you want to continue? + File Manager Path Error Default Web Browser @@ -462,6 +464,10 @@ 1. Upload log file: {0} 2. Copy below exception message + + An error occurred while opening the folder.:\n{0} + Error + Please wait... diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs index 796f65ae6..84448a685 100644 --- a/Flow.Launcher/PublicAPIInstance.cs +++ b/Flow.Launcher/PublicAPIInstance.cs @@ -316,40 +316,63 @@ namespace Flow.Launcher public void OpenDirectory(string DirectoryPath, string FileNameOrFilePath = null) { - using var explorer = new Process(); - var explorerInfo = _settings.CustomExplorer; - var explorerPath = explorerInfo.Path.Trim().ToLowerInvariant(); - var targetPath = FileNameOrFilePath is null - ? DirectoryPath - : Path.IsPathRooted(FileNameOrFilePath) - ? FileNameOrFilePath - : Path.Combine(DirectoryPath, FileNameOrFilePath); + try + { + using var explorer = new Process(); + var explorerInfo = _settings.CustomExplorer; + var explorerPath = explorerInfo.Path.Trim().ToLowerInvariant(); + var targetPath = FileNameOrFilePath is null + ? DirectoryPath + : Path.IsPathRooted(FileNameOrFilePath) + ? FileNameOrFilePath + : Path.Combine(DirectoryPath, FileNameOrFilePath); - if (Path.GetFileNameWithoutExtension(explorerPath) == "explorer") - { - // Windows File Manager - // We should ignore and pass only the path to Shell to prevent zombie explorer.exe processes - explorer.StartInfo = new ProcessStartInfo + if (Path.GetFileNameWithoutExtension(explorerPath) == "explorer") { - FileName = targetPath, // Not explorer, Only path. - UseShellExecute = true // Must be true to open folder - }; - } - else - { - // Custom File Manager - explorer.StartInfo = new ProcessStartInfo + // Windows File Manager + explorer.StartInfo = new ProcessStartInfo + { + FileName = targetPath, + UseShellExecute = true + }; + } + else { - FileName = explorerInfo.Path.Replace("%d", DirectoryPath), - UseShellExecute = true, - Arguments = FileNameOrFilePath is null - ? explorerInfo.DirectoryArgument.Replace("%d", DirectoryPath) - : explorerInfo.FileArgument - .Replace("%d", DirectoryPath) - .Replace("%f", targetPath) - }; + // Custom File Manager + explorer.StartInfo = new ProcessStartInfo + { + FileName = explorerInfo.Path.Replace("%d", DirectoryPath), + UseShellExecute = true, + Arguments = FileNameOrFilePath is null + ? explorerInfo.DirectoryArgument.Replace("%d", DirectoryPath) + : explorerInfo.FileArgument + .Replace("%d", DirectoryPath) + .Replace("%f", targetPath) + }; + } + + explorer.Start(); + } + catch (System.ComponentModel.Win32Exception ex) when (ex.NativeErrorCode == 2) + { + // File Manager not found + MessageBoxEx.Show( + string.Format(GetTranslation("fileManagerNotFound"), ex.Message), + GetTranslation("fileManagerNotFoundTitle"), + MessageBoxButton.OK, + MessageBoxImage.Error + ); + } + catch (Exception ex) + { + // Other exceptions + MessageBoxEx.Show( + string.Format(GetTranslation("folderOpenError"), ex.Message), + GetTranslation("errorTitle"), + MessageBoxButton.OK, + MessageBoxImage.Error + ); } - explorer.Start(); } private void OpenUri(Uri uri, bool? inPrivate = null) diff --git a/Flow.Launcher/SelectFileManagerWindow.xaml.cs b/Flow.Launcher/SelectFileManagerWindow.xaml.cs index bf94ddacb..d2f7ae764 100644 --- a/Flow.Launcher/SelectFileManagerWindow.xaml.cs +++ b/Flow.Launcher/SelectFileManagerWindow.xaml.cs @@ -1,5 +1,8 @@ -using System.Collections.ObjectModel; +using System; +using System.Collections.ObjectModel; using System.ComponentModel; +using System.Diagnostics; +using System.IO; using System.Linq; using System.Windows; using System.Windows.Controls; @@ -43,11 +46,62 @@ namespace Flow.Launcher private void btnDone_Click(object sender, RoutedEventArgs e) { + // Check if the selected file manager path is valid + if (!IsFileManagerValid(CustomExplorer.Path)) + { + MessageBoxResult result = MessageBoxEx.Show( + string.Format((string)Application.Current.FindResource("fileManagerPathNotFound"), + CustomExplorer.Name, CustomExplorer.Path), + (string)Application.Current.FindResource("fileManagerPathError"), + MessageBoxButton.YesNo, + MessageBoxImage.Warning); + + if (result == MessageBoxResult.No) + { + return; + } + } + _settings.CustomExplorerList = CustomExplorers.ToList(); _settings.CustomExplorerIndex = SelectedCustomExplorerIndex; Close(); } + private bool IsFileManagerValid(string path) + { + if (string.Equals(path, "explorer", StringComparison.OrdinalIgnoreCase)) + return true; + + if (Path.IsPathRooted(path)) + { + return File.Exists(path); + } + + try + { + var process = new Process + { + StartInfo = new ProcessStartInfo + { + FileName = "where", + Arguments = path, + RedirectStandardOutput = true, + UseShellExecute = false, + CreateNoWindow = true + } + }; + process.Start(); + string output = process.StandardOutput.ReadToEnd(); + process.WaitForExit(); + + return !string.IsNullOrEmpty(output); + } + catch + { + return false; + } + } + private void btnAdd_Click(object sender, RoutedEventArgs e) { CustomExplorers.Add(new()