Skip to content

Commit 2c7fb93

Browse files
committed
Add error handling and validation for custom file manager paths
1 parent 037b800 commit 2c7fb93

File tree

3 files changed

+113
-30
lines changed

3 files changed

+113
-30
lines changed

Flow.Launcher/Languages/en.xaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,8 @@
373373
<system:String x:Key="fileManager_path">File Manager Path</system:String>
374374
<system:String x:Key="fileManager_directory_arg">Arg For Folder</system:String>
375375
<system:String x:Key="fileManager_file_arg">Arg For File</system:String>
376+
<system:String x:Key="fileManagerPathNotFound">The path for the file manager '{0}' could not be found: {1}\n\nDo you want to continue?</system:String>
377+
<system:String x:Key="fileManagerPathError">File Manager Path Error</system:String>
376378

377379
<!-- DefaultBrowser Setting Dialog -->
378380
<system:String x:Key="defaultBrowserTitle">Default Web Browser</system:String>
@@ -462,6 +464,10 @@
462464
<system:String x:Key="reportWindow_upload_log">1. Upload log file: {0}</system:String>
463465
<system:String x:Key="reportWindow_copy_below">2. Copy below exception message</system:String>
464466

467+
<!-- File Open Error -->
468+
<system:String x:Key="folderOpenError">An error occurred while opening the folder.:\n{0}</system:String>
469+
<system:String x:Key="errorTitle">Error</system:String>
470+
465471
<!-- General Notice -->
466472
<system:String x:Key="pleaseWait">Please wait...</system:String>
467473

Flow.Launcher/PublicAPIInstance.cs

Lines changed: 52 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -316,40 +316,63 @@ public void SavePluginSettings()
316316

317317
public void OpenDirectory(string DirectoryPath, string FileNameOrFilePath = null)
318318
{
319-
using var explorer = new Process();
320-
var explorerInfo = _settings.CustomExplorer;
321-
var explorerPath = explorerInfo.Path.Trim().ToLowerInvariant();
322-
var targetPath = FileNameOrFilePath is null
323-
? DirectoryPath
324-
: Path.IsPathRooted(FileNameOrFilePath)
325-
? FileNameOrFilePath
326-
: Path.Combine(DirectoryPath, FileNameOrFilePath);
327-
328-
if (Path.GetFileNameWithoutExtension(explorerPath) == "explorer")
319+
try
329320
{
330-
// Windows File Manager
331-
// We should ignore and pass only the path to Shell to prevent zombie explorer.exe processes
332-
explorer.StartInfo = new ProcessStartInfo
321+
using var explorer = new Process();
322+
var explorerInfo = _settings.CustomExplorer;
323+
var explorerPath = explorerInfo.Path.Trim().ToLowerInvariant();
324+
var targetPath = FileNameOrFilePath is null
325+
? DirectoryPath
326+
: Path.IsPathRooted(FileNameOrFilePath)
327+
? FileNameOrFilePath
328+
: Path.Combine(DirectoryPath, FileNameOrFilePath);
329+
330+
if (Path.GetFileNameWithoutExtension(explorerPath) == "explorer")
333331
{
334-
FileName = targetPath, // Not explorer, Only path.
335-
UseShellExecute = true // Must be true to open folder
336-
};
332+
// Windows File Manager
333+
explorer.StartInfo = new ProcessStartInfo
334+
{
335+
FileName = targetPath,
336+
UseShellExecute = true
337+
};
338+
}
339+
else
340+
{
341+
// Custom File Manager
342+
explorer.StartInfo = new ProcessStartInfo
343+
{
344+
FileName = explorerInfo.Path.Replace("%d", DirectoryPath),
345+
UseShellExecute = true,
346+
Arguments = FileNameOrFilePath is null
347+
? explorerInfo.DirectoryArgument.Replace("%d", DirectoryPath)
348+
: explorerInfo.FileArgument
349+
.Replace("%d", DirectoryPath)
350+
.Replace("%f", targetPath)
351+
};
352+
}
353+
354+
explorer.Start();
337355
}
338-
else
356+
catch (System.ComponentModel.Win32Exception ex) when (ex.NativeErrorCode == 2)
339357
{
340-
// Custom File Manager
341-
explorer.StartInfo = new ProcessStartInfo
342-
{
343-
FileName = explorerInfo.Path.Replace("%d", DirectoryPath),
344-
UseShellExecute = true,
345-
Arguments = FileNameOrFilePath is null
346-
? explorerInfo.DirectoryArgument.Replace("%d", DirectoryPath)
347-
: explorerInfo.FileArgument
348-
.Replace("%d", DirectoryPath)
349-
.Replace("%f", targetPath)
350-
};
358+
// File Manager not found
359+
MessageBoxEx.Show(
360+
string.Format(GetTranslation("fileManagerNotFound"), ex.Message),
361+
GetTranslation("fileManagerNotFoundTitle"),
362+
MessageBoxButton.OK,
363+
MessageBoxImage.Error
364+
);
365+
}
366+
catch (Exception ex)
367+
{
368+
// Other exceptions
369+
MessageBoxEx.Show(
370+
string.Format(GetTranslation("folderOpenError"), ex.Message),
371+
GetTranslation("errorTitle"),
372+
MessageBoxButton.OK,
373+
MessageBoxImage.Error
374+
);
351375
}
352-
explorer.Start();
353376
}
354377

355378
private void OpenUri(Uri uri, bool? inPrivate = null)

Flow.Launcher/SelectFileManagerWindow.xaml.cs

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1-
using System.Collections.ObjectModel;
1+
using System;
2+
using System.Collections.ObjectModel;
23
using System.ComponentModel;
4+
using System.Diagnostics;
5+
using System.IO;
36
using System.Linq;
47
using System.Windows;
58
using System.Windows.Controls;
@@ -43,11 +46,62 @@ private void btnCancel_Click(object sender, RoutedEventArgs e)
4346

4447
private void btnDone_Click(object sender, RoutedEventArgs e)
4548
{
49+
// Check if the selected file manager path is valid
50+
if (!IsFileManagerValid(CustomExplorer.Path))
51+
{
52+
MessageBoxResult result = MessageBoxEx.Show(
53+
string.Format((string)Application.Current.FindResource("fileManagerPathNotFound"),
54+
CustomExplorer.Name, CustomExplorer.Path),
55+
(string)Application.Current.FindResource("fileManagerPathError"),
56+
MessageBoxButton.YesNo,
57+
MessageBoxImage.Warning);
58+
59+
if (result == MessageBoxResult.No)
60+
{
61+
return;
62+
}
63+
}
64+
4665
_settings.CustomExplorerList = CustomExplorers.ToList();
4766
_settings.CustomExplorerIndex = SelectedCustomExplorerIndex;
4867
Close();
4968
}
5069

70+
private bool IsFileManagerValid(string path)
71+
{
72+
if (string.Equals(path, "explorer", StringComparison.OrdinalIgnoreCase))
73+
return true;
74+
75+
if (Path.IsPathRooted(path))
76+
{
77+
return File.Exists(path);
78+
}
79+
80+
try
81+
{
82+
var process = new Process
83+
{
84+
StartInfo = new ProcessStartInfo
85+
{
86+
FileName = "where",
87+
Arguments = path,
88+
RedirectStandardOutput = true,
89+
UseShellExecute = false,
90+
CreateNoWindow = true
91+
}
92+
};
93+
process.Start();
94+
string output = process.StandardOutput.ReadToEnd();
95+
process.WaitForExit();
96+
97+
return !string.IsNullOrEmpty(output);
98+
}
99+
catch
100+
{
101+
return false;
102+
}
103+
}
104+
51105
private void btnAdd_Click(object sender, RoutedEventArgs e)
52106
{
53107
CustomExplorers.Add(new()

0 commit comments

Comments
 (0)