Handle invalid CWD when creating file dialogs - #840
Conversation
2cda1cb to
ba9d7ec
Compare
|
@cyanfish it would be great if you can consider this for the next release |
|
|
||
| private static void SetSafeCurrentDirectory() | ||
| { | ||
| var fallbackDirectory = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); |
There was a problem hiding this comment.
SpecialFolder.MyDocuments probably makes more sense for Windows (Windows users don't usually access the user profile folder)
There was a problem hiding this comment.
Updated: fallback now uses SpecialFolder.MyDocuments on Windows and SpecialFolder.UserProfile on non-Windows.
| var fallbackDirectory = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); | ||
| if (string.IsNullOrWhiteSpace(fallbackDirectory) || !Directory.Exists(fallbackDirectory)) | ||
| { | ||
| fallbackDirectory = Path.GetTempPath(); |
There was a problem hiding this comment.
I don't think this is necessary, and TempPath doesn't really make sense as a fallback anyway
There was a problem hiding this comment.
Done — removed the TempPath fallback entirely.
| { | ||
| fallbackDirectory = Path.GetTempPath(); | ||
| } | ||
| Environment.CurrentDirectory = fallbackDirectory; |
There was a problem hiding this comment.
Setting FileDialog.Directory probably makes more sense than changing the environment
There was a problem hiding this comment.
Updated to prefer FileDialog.Directory defaults now: if no explicit path is provided, dialogs are pointed at the platform fallback directory. Environment.CurrentDirectory is only set in the constructor-exception recovery path.
| try | ||
| { | ||
| var currentDirectory = Directory.GetCurrentDirectory(); | ||
| if (!Directory.Exists(currentDirectory)) |
There was a problem hiding this comment.
We do three different checks:
- Check if the current directory exists
- Catch exceptions when checking the current directory
- Catch FileNotFoundException when creating a dialog
Which of these is actually necessary? Ideally we'd handle this in one way.
There was a problem hiding this comment.
Good point — simplified this to one primary handling path: catch FileNotFoundException during dialog construction, set a platform fallback CWD, then retry once. Removed the separate pre-check logic.
| { | ||
| FileName = GetDefaultFileName(defaultPath, lastExt!) | ||
| }; | ||
| var sd = CreateSaveFileDialog(); |
There was a problem hiding this comment.
To confirm, I assume you've tested this just on Linux (and not Windows/Mac)?
There was a problem hiding this comment.
Yes, issue reproduction and validation were on Linux. I have not run Windows/Mac runtime validation in this environment.
|
Implemented the requested updates in commit 273089d:
Also confirming: reproduction and validation for this bug were done on Linux in this environment. |
273089d to
0e6096b
Compare
Summary
SaveFileDialogis created while the process current working directory has been deleted/unmountedSaveFileDialogconstruction after setting a safe fallback directoryOpenFileDialogcreationRoot cause
On Linux/GTK, constructing Eto file dialogs may call
Environment.CurrentDirectory(GetCwd). If the original working directory no longer exists, this throwsSystem.IO.FileNotFoundExceptionand the dialog never opens.Changes
NAPS2.Lib/EtoForms/EtoDialogHelper.csEnsureCurrentDirectoryIsAccessible()SetSafeCurrentDirectory()with fallback order:Environment.SpecialFolder.UserProfilePath.GetTempPath()CreateSaveFileDialog()wrapper that catchesFileNotFoundException, resets CWD, and retriesCreateSaveFileDialog()inPromptToSavePdfOrImage,PromptToSavePdf, andPromptToSaveImageEnsureCurrentDirectoryIsAccessible()inPromptToImportValidation
EtoDialogHelper.cs: cleandotnetCLI unavailable)Fixes #839