Skip to content

Commit e21d9b2

Browse files
authored
Merge pull request #840 from nikoskalogridis/fix/savefiledialog-invalid-cwd-crash
Handle invalid CWD when creating file dialogs
2 parents 2ea9747 + 0e6096b commit e21d9b2

1 file changed

Lines changed: 57 additions & 25 deletions

File tree

NAPS2.Lib/EtoForms/EtoDialogHelper.cs

Lines changed: 57 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,8 @@ public override bool PromptToSavePdfOrImage(string? defaultPath, out string? sav
2222
{
2323
lastExt = "pdf";
2424
}
25-
var sd = new SaveFileDialog
26-
{
27-
FileName = GetDefaultFileName(defaultPath, lastExt!)
28-
};
25+
var sd = CreateSaveFileDialog();
26+
sd.FileName = GetDefaultFileName(defaultPath, lastExt!);
2927
_fileFilters.Set(sd, FileFilterGroup.Pdf | FileFilterGroup.Image, lastExt);
3028
SetDir(sd, defaultPath);
3129
EtoPlatform.Current.ConfigureFileDialog(sd);
@@ -41,10 +39,8 @@ public override bool PromptToSavePdfOrImage(string? defaultPath, out string? sav
4139

4240
public override bool PromptToSavePdf(string? defaultPath, out string? savePath)
4341
{
44-
var sd = new SaveFileDialog
45-
{
46-
FileName = GetDefaultFileName(defaultPath, "pdf")
47-
};
42+
var sd = CreateSaveFileDialog();
43+
sd.FileName = GetDefaultFileName(defaultPath, "pdf");
4844
_fileFilters.Set(sd, FileFilterGroup.Pdf);
4945
SetDir(sd, defaultPath);
5046
EtoPlatform.Current.ConfigureFileDialog(sd);
@@ -64,10 +60,8 @@ public override bool PromptToSaveImage(string? defaultPath, out string? savePath
6460
{
6561
lastExt = "jpg";
6662
}
67-
var sd = new SaveFileDialog
68-
{
69-
FileName = GetDefaultFileName(defaultPath, lastExt!)
70-
};
63+
var sd = CreateSaveFileDialog();
64+
sd.FileName = GetDefaultFileName(defaultPath, lastExt!);
7165
var filterGroups = EtoPlatform.Current.IsGtk
7266
? FileFilterGroup.AllImages | FileFilterGroup.Image
7367
: FileFilterGroup.Image;
@@ -96,18 +90,62 @@ public override bool PromptToSaveImage(string? defaultPath, out string? savePath
9690
: normPath;
9791
}
9892

99-
private void SetDir(SaveFileDialog dialog, string? defaultPath)
93+
private static SaveFileDialog CreateSaveFileDialog()
94+
{
95+
try
96+
{
97+
return new SaveFileDialog();
98+
}
99+
catch (FileNotFoundException) when (TrySetCurrentDirectoryForDialogFallback())
100+
{
101+
return new SaveFileDialog();
102+
}
103+
}
104+
105+
private static OpenFileDialog CreateOpenFileDialog()
106+
{
107+
try
108+
{
109+
return new OpenFileDialog();
110+
}
111+
catch (FileNotFoundException) when (TrySetCurrentDirectoryForDialogFallback())
112+
{
113+
return new OpenFileDialog();
114+
}
115+
}
116+
117+
private static bool TrySetCurrentDirectoryForDialogFallback()
118+
{
119+
var fallbackDirectory = GetDialogFallbackDirectory();
120+
if (fallbackDirectory == null)
121+
{
122+
return false;
123+
}
124+
Environment.CurrentDirectory = fallbackDirectory;
125+
return true;
126+
}
127+
128+
private static string? GetDialogFallbackDirectory()
129+
{
130+
var fallbackDirectory = Environment.GetFolderPath(OperatingSystem.IsWindows()
131+
? Environment.SpecialFolder.MyDocuments
132+
: Environment.SpecialFolder.UserProfile);
133+
return Directory.Exists(fallbackDirectory) ? fallbackDirectory : null;
134+
}
135+
136+
private void SetDir(FileDialog dialog, string? defaultPath)
100137
{
101138
string? path = null;
102139
if (Paths.IsTestAppDataPath)
103140
{
104141
// For UI test automation we choose the appdata folder for test isolation and consistency
105142
path = Paths.AppData;
106143
}
107-
else if (Path.IsPathRooted(defaultPath))
144+
else if (!string.IsNullOrEmpty(defaultPath) && Path.IsPathRooted(defaultPath))
108145
{
109146
path = Path.GetDirectoryName(NormalizePath(defaultPath));
110147
}
148+
path ??= GetDialogFallbackDirectory();
111149
if (path != null)
112150
{
113151
dialog.Directory = UriHelper.FilePathToFileUri(Path.GetFullPath(path));
@@ -128,18 +166,12 @@ private static string NormalizePath(string path)
128166

129167
public override bool PromptToImport(out string[]? filePaths)
130168
{
131-
var ofd = new OpenFileDialog
132-
{
133-
MultiSelect = true,
134-
CheckFileExists = true
135-
};
169+
var ofd = CreateOpenFileDialog();
170+
ofd.MultiSelect = true;
171+
ofd.CheckFileExists = true;
136172
_fileFilters.Set(ofd,
137173
FileFilterGroup.AllFiles | FileFilterGroup.Pdf | FileFilterGroup.AllImages | FileFilterGroup.Image);
138-
if (Paths.IsTestAppDataPath)
139-
{
140-
// For UI test automation we choose the appdata folder to find the prepared files to import
141-
ofd.Directory = UriHelper.FilePathToFileUri(Path.GetFullPath(Paths.AppData));
142-
}
174+
SetDir(ofd, defaultPath: null);
143175
EtoPlatform.Current.ConfigureFileDialog(ofd);
144176
if (ofd.ShowDialog(null) == DialogResult.Ok)
145177
{
@@ -149,4 +181,4 @@ public override bool PromptToImport(out string[]? filePaths)
149181
filePaths = null;
150182
return false;
151183
}
152-
}
184+
}

0 commit comments

Comments
 (0)