问题
One of my customers is experiencing a crash in my WPF application when saving a file.
My save file code is:
var saveFileDialog = new SaveFileDialog {
InitialDirectory = string.Concat(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), @"\MyApp"),
FileName = "MyFile",
OverwritePrompt = true,
AddExtension = true
};
if (saveFileDialog.ShowDialog() == true) {
...
}
And here is the exception they are getting:
Value does not fall within the expected range.
A System.ArgumentException occurred
at MS.Internal.Interop.HRESULT.ThrowIfFailed(String message)
at MS.Internal.AppModel.ShellUtil.GetShellItemForPath(String path)
at Microsoft.Win32.FileDialog.PrepareVistaDialog(IFileDialog dialog)
at Microsoft.Win32.FileDialog.RunVistaDialog(IntPtr hwndOwner)
at Microsoft.Win32.FileDialog.RunDialog(IntPtr hwndOwner)
at Microsoft.Win32.CommonDialog.ShowDialog()
(Where the ShowDialog
in the last line refers to the call I make in my code above.)
So my hunch is that in my customer's case, the call to Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) is returning something that the SaveFileDialog
does not like as the InitialDirectory
. I've found in web searches (and validated) that this error occurs when passing a relative path as the InitialDirectory
of the SaveFileDialog. Is it possible that Environment.SpecialFolder.MyDocuments
could be returned as a relative path? If not, does anybody know another potentially invalid format? Could a certain SpecialFolder.MyDocuments network path be the cause? Any other ideas?
I don't have direct access to my customer's machine and they aren't particularly tech savvy so it's not possible to be 100% certain what is happening.
回答1:
I found that using
fullPath = System.IO.Path.GetFullPath(relPath);
eliminated the problem for me.
Apparently, FileDialog.ShowDialog
does not like relative InitialDirectory
values.
回答2:
Found it.
InitialDirectory = string.Concat(
Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
@"\MyApp"
)
Environment.SpecialFolder.MyDocuments
was being returned on my customer's machine with a trailing '\' character, and so the complete concatenated path had a double '\' in it.
SaveFileDialog
crashes when you pass an InitialDirectory
path containing a double '\' (which is a flaw in my opinion - it should more gracefully handle or coerce invalid inputs).
I use the Path.Combine
static method instead now to handle both variants:
InitialDirectory = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
"MyApp"
)
And it crashes no more.
回答3:
For those who had the same problem:
The exception also happens when Environment.SpecialFolder.MyDocuments
points to a network drive (domain environment) and it somehow is not reachable. Then GetFullPath
or Path.Combine
does not help.
I solved it catching the exception and calling ShowDialog a second time after setting InitialDirectory to the System Root, e.g. "C:\".
来源:https://stackoverflow.com/questions/9875456/savefiledialog-exception-in-my-wpf-app