2

When using SaveFileDialog, I noticed that there is a difference in the behavior between WPF and WindowsForms when the path is too long.

To verify this, create a long folder name (but not more than the allowed 247 chars), for example:

C:\LooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongFolder

Create a WindowsForms project and a button on the Form with a click event:

using System;
using System.Diagnostics;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            SaveFileDialog sFile = new SaveFileDialog();
            sFile.FileName = "Test.txt";
            if (sFile.ShowDialog() == DialogResult.Yes)
                Debug.Print(sFile.FileName);
        }
    }
}

Start the program, move to the long folder in the SaveFileDialog, enter a long enough name, like "MyLittleTextFile.txt", and press enter.

sFile.FileName will throw an internal exception and thus Debug.Print will not be executed.

Now create a WPF project and a button on the MainWindow with a click event:

using System.Diagnostics;
using System.Windows;
using Microsoft.Win32;

namespace WpfApplication1
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void button_Click(object sender, RoutedEventArgs e)
        {
            SaveFileDialog sFile = new SaveFileDialog();
            sFile.FileName = "Test.txt";
            if (sFile.ShowDialog() == true)
                Debug.Print(sFile.FileName);
        }
    }
}

Again start the program, move to the long folder in the SaveFileDialog, enter a long enough name, like "MyLittleTextFile.txt", and press enter.

sFile.FileName will now still throw an internal exception, but it will simply return to the old value of "Test.txt".

This is surprising at best, because at this point of course I expect the value to be the one I selected - or getting an error when trying to use it. Having the old value doesn't make much sense in my eyes. Anybody knows why it was implemented this way? Is this desired behavior, or is it a bug?

Thern
  • 1,017
  • 8
  • 17
  • ...throws an internal exception... which one? [this one](https://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/SaveFileDialog.cs,211)? Both Winforms and WPF use different layers of abstraction to the underlying commdlg calls, so at least its not impossible to see implementation differences. – Cee McSharpface Sep 19 '18 at 15:35
  • @dlatikay Output window says "Exception thrown: 'System.IO.PathTooLongException' in mscorlib.dll". I'm fine with different implementations, but falling back to the previous value when a (normally invisible) exception appears seems confusing for me. At least I spent half a day to find the root cause for the strange behavior I was seeing. – Thern Sep 19 '18 at 15:37
  • are you saying that in the WPF case, `ShowDialog()` returns true? because if it returned false, which I'd have expected, the caller is not supposed to use the `FileName` property. – Cee McSharpface Sep 19 '18 at 15:59
  • @dlatikay It returns DialogResult.OK or DialogResult.Cancel depending on if you click Save or Cancel. I tried this scenario and I'm unable to get it to allow me to enter a name that would be longer than MAX_PATH. If the length of the Filename exceeds MAX_PATH it simply won't let me save it. I click Save and it does nothing. https://gfycat.com/FailingOldfashionedGnu – fourwhey Sep 19 '18 at 16:06
  • just asking, because in the second, "WPF" example, OP is using the `Microsoft.Win32` namespace which obviously means the `Microsoft.Win32.SaveFileDialog`, which does [return a bool](https://learn.microsoft.com/de-de/dotnet/api/microsoft.win32.savefiledialog?redirectedfrom=MSDN&view=netframework-4.7.2). – Cee McSharpface Sep 19 '18 at 16:13
  • @dlatikay Right, I am about to try that as well. I was testing the WinForms one first. I suspect it will behave similarly in that it simply won't allow the path + file to be saved if it abides by MAX_PATH. – fourwhey Sep 19 '18 at 16:15
  • It is rather boring to dig further, but if you like, the source code is available, https://referencesource.microsoft.com/#q=SaveFileDialog – Lex Li Sep 19 '18 at 16:22
  • For WPF it seems to allow the save, and the debug output doesn't result in an error. It looks like it's utilizing a \\?\ UNC path though. Which version of the framework are you targeting? There have been changes in recent framework updates around adding better support for long filenames, paths, etc. Here's the output `\\?\C:\LooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongFolder\MyLittleTextFile.txt` – fourwhey Sep 19 '18 at 16:24
  • @dlatikay Yes, it indeed returns true. I would not have expected this as well. – Thern Sep 19 '18 at 16:39
  • @fourwhey I use the .NET framework V4.7.03062. – Thern Sep 19 '18 at 16:40
  • I'm using the same version and it seems to work for me. – fourwhey Sep 19 '18 at 17:24
  • @fourwhey Debug output for WPF doesn't result in error, but is "Test.txt". – Thern Sep 19 '18 at 19:29
  • related https://stackoverflow.com/questions/7067663/how-to-close-win32-savefiledialog-when-an-error-has-occurred, additional recherche https://social.msdn.microsoft.com/Forums/en-US/9dfb1c0d-0c83-4ab4-b1e1-714f1d5f154a/savefiledialog-bug?forum=wpf – Cee McSharpface Sep 19 '18 at 20:37

1 Answers1

0

This was on Windows 10 (17134.285) targeting FW 4.7.

When entering a long filename...

sFile.FileName Will contain the full UNC path. (see below)

\\?\C:\LooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongFolder\MyLittleTextFile.txt

sFile.SafeFileName Will contain the filename only.

MyLittleTextFile.txt

enter image description here

With WinForms I was unable to force the dialog to accept a long filename, leaving only a shorter filename or cancelling as an option.

No exceptions were thrown.

fourwhey
  • 490
  • 4
  • 19