question

KennyMike-7550 avatar image
0 Votes"
KennyMike-7550 asked KennyMike-7550 answered

SaveFileDialog does not allow long pathnames to be returned

In testing our internal tools for handling long pathnames (>MAX_PATH), I've come across the following issue with
System.Windows.Forms.SaveFileDialog
(in .Net 4.8 on Windows 10)

Exception Text
Message: The given path's format is not supported.
Exception Type: System.NotSupportedException
Source: mscorlib
StrackTrace:
at System.Security.Util.StringExpressionSet.CanonicalizePath(String path, Boolean needFullPath)
at System.Security.Util.StringExpressionSet.CreateListFromExpressions(String[] str, Boolean needFullPath)
at System.Security.Permissions.FileIOPermission.AddPathList(FileIOPermissionAccess access, AccessControlActions control, String[] pathListOrig, Boolean checkForDuplicates, Boolean needFullPath, Boolean copyPathList)
at System.Security.Permissions.FileIOPermission..ctor(FileIOPermissionAccess access, String path)
at System.Windows.Forms.IntSecurity.DemandFileIO(FileIOPermissionAccess access, String fileName)
at System.Windows.Forms.FileDialog.get_FileName()
at .FileSaveAs

To repeat this, you navigate into a directory which is deeper than MAX_PATH, and click ok to save your file there.
You get the above.

That's a little disappointing considering the amount of effort to manage \\?\ we're having to do.
We're using .Net 4.8, where we've replaced System.IO.File.Create / Open / WriteAllText etc to use a NativeMethods.CreateFile from kernel32.dll to support long pathname versions of these functions. (ref. the ms LongPathnames articles and sample code)

Can we fix this SaveFileDialog issue?
Is it fixed in .Net Core out of interest? Not that we can migrate to that quite yet.

Note: You get a slightly different call stack if saveDlg.OverwritePrompt = true, but it boils down to the same issue with CannonicalisePath.

Kind Regards.


dotnet-csharpwindows-forms
· 6
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Do you have a code snippet you can share with us to illustrate what you're trying to do that shows up the problem.
If I try a simple use of SaveFileDialog, it can navigate a very long path, and returns the short file name.

0 Votes 0 ·

I did some tests and I cannot get your error message (.NET 4.7.2, Windows 10)
And I can save paths > 260 with IFileSaveDialog (with LongPathsEnabled = 1 in registry)

0 Votes 0 ·

Hi, sorry for the delay and thanks for your responses.
Ok that's interesting. I'd not come across:
Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem\LongPathsEnabled
(or perhaps I have and have forgotten about it).
Anyway, needless to say this is 0 on a couple of machines I've so far tried.
I've set this to 1, and re-booted one of the machines. I still get the same issue on that.
The path I'm attempting to save to is:
C:\Temp\LongNames\shader_p_longnames_longnames_longnames_longnames_longnames_longnames_longnames_longnames_longnames_longnames_longnames_longnames_longnames_longnames_longnames_longnames_longnames_longnames_d89ab0fc3e9786d6\
And the filename is:
GPU_Capture_tutorial_post_processing_2021_01_13_18_10_14.xyzabc
I get the same error on my Win10 Laptop and desktop machine interestingly. They both probably have the same security stack, so it could be something in there?





0 Votes 0 ·

The actual code doing this is extremely trivial, where pathSaveFile is the leafname above.

using (SaveFileDialog sfd = new SaveFileDialog())
{
sfd.OverwritePrompt = true;
sfd.FileName = pathSaveFile;
sfd.AddExtension = true;
sfd.DefaultExt = "xyzabc";
sfd.Filter = "Project Files (.xyzabc)|.xyzabc";

 DialogResult dlgResult = sdf.ShowDialog();
 if (dlgResult != DialogResult.OK)
     return false;
    pathSaveFile = sfd.FileName;

}

I'll see if I can't test it on a vanilla Win10 vm.

Thanks

0 Votes 0 ·
Show more comments

If you don't find a solution with SaveFileDialog, you can test IFileSaveDialog
In my test, the long file name is correctly converted into "\\?\E:\:..." : IFile-Dialog-Longpath.jpg




0 Votes 0 ·

1 Answer

KennyMike-7550 avatar image
0 Votes"
KennyMike-7550 answered

Hi again
Thanks for the IFileSaveDialog suggestion. In my test I can get the pathname back from that interface for long paths.
Unfortunately I can't get SaveFileDialog to not throw an exception in this example but as far as I know it could be any number of FS layers or filters that are local to my setups
(if that's involved).
Anyway, I can get around it with
internal const string IFileSaveDialog = "84bccd23-5fde-4cdb-aea4-af64b83d78ab";
Urg. Not so easy to use - but I guess it will do.
Thanks - this can be closed as not repeatable unless you need me to try something else?




5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.