C# OpenFileDialog在超过260个字符的路径上返回空字符串(或者根本不返回)

C# OpenFileDialog在超过260个字符的路径上返回空字符串(或者根本不返回),c#,.net,openfiledialog,max-path,C#,.net,Openfiledialog,Max Path,我正在写一个程序,需要从系统的任何地方读入文件。程序的某些用户的路径超过260个字符的限制。OpenFileDialog无法处理路径超过260个字符的文件 我尝试过使用System.Windows.Forms.OpenFileDialog和Microsoft.Win32.OpenFileDialog。对于前者,当我导航到并选择文件后单击“打开”时,窗口不会关闭,程序也不会继续。对于后者,当我单击“打开”时窗口将关闭,但路径是空字符串 我已经在我的计算机上更新了注册表。我已经编辑了应用程序清单文件

我正在写一个程序,需要从系统的任何地方读入文件。程序的某些用户的路径超过260个字符的限制。
OpenFileDialog
无法处理路径超过260个字符的文件

我尝试过使用
System.Windows.Forms.OpenFileDialog
Microsoft.Win32.OpenFileDialog
。对于前者,当我导航到并选择文件后单击“打开”时,窗口不会关闭,程序也不会继续。对于后者,当我单击“打开”时窗口将关闭,但路径是空字符串

我已经在我的计算机上更新了注册表。我已经编辑了应用程序清单文件。我会尝试将“//”字符串前置到我的路径,但没有要前置的路径

var dialog = new OpenFileDialog
{
  // initialize dialog
}

if (dialog.ShowDialog() == DialogResult.OK) // DialogResult.OK replaced with true if using Microsoft.Win32.OpenFileDialog
{
  // if when using System.Windows.Forms.OpenFileDialog, I will never get to this point
  // if using Microsoft.Win32.OpenFileDialog, I will get here but dialog.FileNames will be empty
}

如果我已经更新了注册表和应用程序清单,我希望上面的代码在长路径和短路径上都能工作。我怀疑这是不受支持的,但我所有的搜索都显示,人们提供的解决方案要么不起作用,要么只在特定情况下起作用。

System.Windows.Forms.OpenFileDialog
的情况下,我可以通过将
ValidateNames
设置为false来克服
ShowDialog()
当用户单击“打开”时不返回

和反射,以克服无法从
文件路径
文件路径
属性访问的路径。事实证明,这些路径存在于一个私有属性中,我可以使用反射来访问它

public static class OpenFileDialogLongPathExtension
{
    public static string[] getFileNames_WindowsForms(this System.Windows.Forms.OpenFileDialog dialog)
    {
        var fileNamesProperty = dialog.GetType().GetProperty("FileNamesInternal", BindingFlags.NonPublic | BindingFlags.Instance);
        var fileNamesFromProperty = (string[])fileNamesProperty?.GetValue(dialog);
        return fileNamesFromProperty;
    }
}
我为Microsoft.Win32.OpenFileDialog尝试了类似的方法,但似乎私有属性仍然无效,因此相同的解决方案不起作用


不管怎样,我希望这能帮助其他人。此示例是使用.NET Framework 4.8创建的。

您的目标是哪个.NET框架?显然,4.6.2及更高版本不应该有问题。我的目标是框架4.7.2。
public static class OpenFileDialogLongPathExtension
{
    public static string[] getFileNames_WindowsForms(this System.Windows.Forms.OpenFileDialog dialog)
    {
        var fileNamesProperty = dialog.GetType().GetProperty("FileNamesInternal", BindingFlags.NonPublic | BindingFlags.Instance);
        var fileNamesFromProperty = (string[])fileNamesProperty?.GetValue(dialog);
        return fileNamesFromProperty;
    }
}