C# OpenFileDialog默认路径 使用(var openFileDialog1=new OpenFileDialog()) { openFileDialog1.Reset(); 如果(!string.IsNullOrEmpty(ExcelFilePath)) { 字符串fileName=Path.GetFileName(ExcelFilePath); 字符串fileExt=Path.GetExtension(ExcelFilePath); //避免出现“无法使用此程序文件打开此位置”对话框 //如果路径中有文件名,请将其删除) 如果(!string.IsNullOrEmpty(文件名)) initialDirectory=Path.GetDirectoryName(ExcelFilePath); //如果不是,就让它去吧 其他的 initialDirectory=ExcelFilePath; openFileDialog1.InitialDirectory=InitialDirectory; } 其他的 openFileDialog1.InitialDirectory=“c:\\”; openFileDialog1.Filter=“Excel文件(*.xls或*.xlsx)|*.xls;*.xlsx”; //openFileDialog1.Filter=“xls文件(*.xls)|*.xls | xlsx文件(*.xlsx)|.xlsx”; openFileDialog1.FilterIndex=2; openFileDialog1.RestoreDirectory=false; openFileDialog1.CheckFileExists=true; openFileDialog1.CheckPathExists=true; 如果(openFileDialog1.ShowDialog()==DialogResult.OK) { var BrowseSelectionMake=BrowseSelectionMake; 如果(BrowseSelectionMake!=null) BrowseSelectionMake(这是新的DataEventArgs(openFileDialog1.FileName)); } }

C# OpenFileDialog默认路径 使用(var openFileDialog1=new OpenFileDialog()) { openFileDialog1.Reset(); 如果(!string.IsNullOrEmpty(ExcelFilePath)) { 字符串fileName=Path.GetFileName(ExcelFilePath); 字符串fileExt=Path.GetExtension(ExcelFilePath); //避免出现“无法使用此程序文件打开此位置”对话框 //如果路径中有文件名,请将其删除) 如果(!string.IsNullOrEmpty(文件名)) initialDirectory=Path.GetDirectoryName(ExcelFilePath); //如果不是,就让它去吧 其他的 initialDirectory=ExcelFilePath; openFileDialog1.InitialDirectory=InitialDirectory; } 其他的 openFileDialog1.InitialDirectory=“c:\\”; openFileDialog1.Filter=“Excel文件(*.xls或*.xlsx)|*.xls;*.xlsx”; //openFileDialog1.Filter=“xls文件(*.xls)|*.xls | xlsx文件(*.xlsx)|.xlsx”; openFileDialog1.FilterIndex=2; openFileDialog1.RestoreDirectory=false; openFileDialog1.CheckFileExists=true; openFileDialog1.CheckPathExists=true; 如果(openFileDialog1.ShowDialog()==DialogResult.OK) { var BrowseSelectionMake=BrowseSelectionMake; 如果(BrowseSelectionMake!=null) BrowseSelectionMake(这是新的DataEventArgs(openFileDialog1.FileName)); } },c#,C#,无论我是否将RestoreDirectory设置为true,如果初始目录设置为不存在的路径,我将始终浏览到最后使用的目录。OpenFileDialog保存的最后使用的目录在哪里?有没有一种方法可以推翻这种行为?(例如,我总是想将其设置为C:\如果初始目录不存在?检查ExcelFilePath是否存在,检查它是否为null或空,但是如果在块之前检查目录是否存在,如果它没有将值重置为空字符串,则应为golden (是的,您需要在前面应用您的文件名逻辑等)但是,一旦您解析了所有这些内容,就不需要确定目

无论我是否将RestoreDirectory设置为true,如果初始目录设置为不存在的路径,我将始终浏览到最后使用的目录。OpenFileDialog保存的最后使用的目录在哪里?有没有一种方法可以推翻这种行为?(例如,我总是想将其设置为C:\如果初始目录不存在?

检查ExcelFilePath是否存在,检查它是否为null或空,但是如果在块之前检查目录是否存在,如果它没有将值重置为空字符串,则应为golden

(是的,您需要在前面应用您的文件名逻辑等)但是,一旦您解析了所有这些内容,就不需要确定目录是否存在了

using (var openFileDialog1 = new OpenFileDialog())
        {
            openFileDialog1.Reset();
            if (!string.IsNullOrEmpty(ExcelFilePath))
            {
                string fileName = Path.GetFileName(ExcelFilePath);
                string fileExt = Path.GetExtension(ExcelFilePath);
                //Avoid "you can't open this location using this program file" dialog 
                //if there is a file name in the path strip it )
                if (!string.IsNullOrEmpty(fileName))
                    initialDirectory = Path.GetDirectoryName(ExcelFilePath);  
      //if not let it be   
                else
                    initialDirectory = ExcelFilePath;

            openFileDialog1.InitialDirectory = initialDirectory;
            }
            else
                openFileDialog1.InitialDirectory = "c:\\";
            openFileDialog1.Filter = "Excel files (*.xls or *.xlsx)|*.xls;*.xlsx";
            //openFileDialog1.Filter = "xls files (*.xls)|*.xls|xlsx files(*.xlsx)|.xlsx";
            openFileDialog1.FilterIndex = 2;
            openFileDialog1.RestoreDirectory = false;
            openFileDialog1.CheckFileExists = true;
            openFileDialog1.CheckPathExists = true;
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                var browseSelectionMade = BrowseSelectionMade;
                if (browseSelectionMade!=null)
                    browseSelectionMade(this, new DataEventArgs<string>(openFileDialog1.FileName));
            }
        }

看起来你需要做的就是:

if (!Directory.Exists(excelPath))
{
    ExcelFilePath = String.Empty;
}

除非我遗漏了什么。

我不认为有什么内在原因。只需在打开对话框之前进行检查:

string path; // this is the path that you are checking.
if(Directory.Exists(path)) {
    openFileDialog1.InitialDirectory = path;
} else {
    openFileDialog1.InitialDirectory = @"C:\";
} 
上次使用的目录保存在哪里

它存储在注册表中。确切位置取决于Windows版本,对于Win7,它是HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32。快速浏览一下regedit应该会让您确信您不想把它弄糟


简单的解决方法是提供有效的路径。如果计算的值无效,则Directory.Exists返回false,然后提供一个有效值。与Environment.GetFolderPath()返回的Documents文件夹类似。同样,上次使用的扩展名也没有问题,用户很容易识别它,很有可能它恰好接近所需的扩展名。

此外,要设置默认扩展名,您应该设置FilterIndex属性,而不是DefaultExt。见:


这里有一篇关于C#中OpenFileDialog的好文章:

如果您使用存储在某个字符串中的文件名,最好使用Path来剪切文件名(在我的W10上,如果我只提供文件名,则“打开”对话框不会在初始目录中打开):

为了未来的我

记住要做:

    if (!System.IO.Directory.Exists(filename))
    {
        openDlg.InitialDirectory =
            System.IO.Path.GetDirectoryName(filename);
    }

当用户从不再存在的位置(例如USB记忆棒、映射的网络驱动器)打开文件时,这有助于解决此问题-如果InitialDirectory无效,ShowDialog将引发异常。

编辑:在咨询更了解情况的朋友后,事后看来,也许更好的解决方案是显而易见的。只需将您自己的注册表项存储在HKEY_CURRENT_USER\SOFTWARE\YourCompanyOrAppName\Whatevs或类似文件中(不确定最佳做法,或您有读/写权限的文件夹,请自行研究),并完全避免此问题。只需让用户导航到他们想要的位置一次,然后将路径存储在注册表中(作为普通字符串,而不是PIDL)并在下次检索该路径。如需参考,请参阅有关Registry和RegistryKey类的MSDN文章,以及RegistryKey/Methods/SetValue文章中的示例。不过,出于好奇,或者如果有人有一个非常具体的问题需要这个解决方案,我还是会原封不动地离开这篇文章。一如既往,祝你好运

对于将来在这里徘徊的任何可怜的灵魂来说,似乎我找到了如何找到最后使用的目录。正如前面所述,它存储在注册表中,更具体地说,存储在
HKEY\U CURRENT\U USER\Software\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32\OpenSavePidlMRU\
下面是一组用于每个文件扩展名的文件夹,包括用于未知文件扩展名的“*”。我将对txt文件执行此操作,根据需要更改路径。为了访问这个路径,我们创建了一个RegistryKey并调用OpenSubKey(顺便说一句,下面是完整的代码)

这里是一组条目,它们都包含最后打开或保存的项目的PIDL(我们将讨论这个问题)。 注意:文件夹名OpenSavePidlMRU,我见过它被称为OpenSaveMRU,它似乎是用于win10之前的版本。 这里还有一个名为“MRUListEx”的条目,MRU代表“最近使用的”。此条目中有一个索引,该索引项是。。。嗯,最近用的。因此,如果我有10个条目,命名为0到9,最后使用的是9,那么MRUListEx中的第一个字节将是0x09。因此:

string RegistryPath = @"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ComDlg32\\OpenSavePidlMRU\\txt";
RegistryKey rk = Registry.CurrentUser.OpenSubKey(RegistryPath);
最后一个将等于0x09(在我的系统上) 然后我们再次调用GetValue,但对于该条目

byte[] mrulistex = (byte[])rk.GetValue("MRUListEx");
byte Last = mrulistex[0];
这就是问题所在,因为它不会返回一个字节数组,其中每个字节都是文件路径中的一个字符,它会返回称为PIDL的内容。而字节数组似乎
string RegistryPath = @"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ComDlg32\\OpenSavePidlMRU\\txt";
RegistryKey rk = Registry.CurrentUser.OpenSubKey(RegistryPath);
byte[] mrulistex = (byte[])rk.GetValue("MRUListEx");
byte Last = mrulistex[0];
byte[] LastPathByteArray = (byte[])rk.GetValue(Last.ToString());
string LastPath = GetPathFromPIDL(LastPathByteArray);
using Microsoft.Win32; //for the registry class
using System.Runtime.InteropServices; //for converting the PIDL

//GetPathFromPIDL from matt.schechtman at https://stackoverflow.com/a/4318663
[DllImport("shell32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SHGetPathFromIDListW(IntPtr pidl, MarshalAs(UnmanagedType.LPTStr)] StringBuilder pszPath);
private string GetPathFromPIDL(byte[] byteCode)
{
    //MAX_PATH = 260
    StringBuilder builder = new StringBuilder(260);

    IntPtr ptr = IntPtr.Zero;
    GCHandle h0 = GCHandle.Alloc(byteCode, GCHandleType.Pinned);
    try
    {
        ptr = h0.AddrOfPinnedObject();
    }
    finally
    {
        h0.Free();
    }

    SHGetPathFromIDListW(ptr, builder);

    return builder.ToString();
}

public void OnClick_Button_OpenFile(object sender, RoutedEventArgs e)
{
    string RegistryPath = @"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ComDlg32\\OpenSavePidlMRU\\txt";
    RegistryKey rk = Registry.CurrentUser.OpenSubKey(RegistryPath);
    byte[] mrulistex = (byte[])rk.GetValue("MRUListEx");
    byte Last = mrulistex[0];
    byte[] LastPathByteArray = (byte[])rk.GetValue(Last.ToString());
    string LastPath = GetPathFromPIDL(LastPathByteArray);

    // Configure open file dialog box
    Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();`
    dlg.InitialDirectory = LastPath;
    result = dlg.ShowDialog();
    if (result == true)
    {
        string filename = dlg.FileName;
    }
    //etc etc, rest of your code
}