【问题标题】:Opening a folder in explorer and selecting a file在资源管理器中打开文件夹并选择文件
【发布时间】:2010-09-24 23:30:21
【问题描述】:

我正在尝试在资源管理器中打开一个文件夹并选择了一个文件。

以下代码产生文件未找到异常:

System.Diagnostics.Process.Start(
    "explorer.exe /select," 
    + listView1.SelectedItems[0].SubItems[1].Text + "\\" 
    + listView1.SelectedItems[0].Text);

如何让这个命令在 C# 中执行?

【问题讨论】:

    标签: c# explorer


    【解决方案1】:
    // suppose that we have a test.txt at E:\
    string filePath = @"E:\test.txt";
    if (!File.Exists(filePath))
    {
        return;
    }
    
    // combine the arguments together
    // it doesn't matter if there is a space after ','
    string argument = "/select, \"" + filePath +"\"";
    
    System.Diagnostics.Process.Start("explorer.exe", argument);
    

    【讨论】:

    • 这对我来说很重要 :) 它不仅打开了目录,还选择了特定的文件 :) 谢谢问候
    • 它就像一个魅力,但任何想法我们如何才能为多个文件做到这一点?
    • 小注意,如果我的文件路径使用正斜杠,带有文件路径的 /select 参数似乎对我不起作用。因此我必须做 filePath = filePath.Replace('/', '\\');
    • 正如其他地方提到的,您的路径应该包含在引号中——这可以防止目录或文件名包含逗号的问题。
    • 我一直在努力解决这个问题,有时上述方法不起作用,因为文件包含逗号。如果我阅读了 Kaganar 的评论,那会为我节省一个小时的工作时间。我敦促 Samuel Yang 将上面的代码修改为:string argument=@"/select"+"\"" + filePath+"\""
    【解决方案2】:

    使用this method:

    Process.Start(String, String)
    

    第一个参数是应用程序(explorer.exe),第二个方法参数是您运行的应用程序的参数。

    例如:

    在 CMD 中:

    explorer.exe -p
    

    在 C# 中:

    Process.Start("explorer.exe", "-p")
    

    【讨论】:

    • 这不会像 Samuel Yangs answer 那样选择文件
    • -p 不足以选择文件
    【解决方案3】:

    如果您的路径包含逗号,则在使用 Process.Start(ProcessStartInfo) 时,在路径周围加上引号将起作用。

    但是,当使用 Process.Start(string, string) 时它将不起作用。看起来 Process.Start(string, string) 实际上删除了参数中的引号。

    这是一个适合我的简单示例。

    string p = @"C:\tmp\this path contains spaces, and,commas\target.txt";
    string args = string.Format("/e, /select, \"{0}\"", p);
    
    ProcessStartInfo info = new ProcessStartInfo();
    info.FileName = "explorer";
    info.Arguments = args;
    Process.Start(info);
    

    【讨论】:

    • 这应该是公认的答案。它只是缺乏对各种可能的故障(权限问题、错误路径等)的适当异常处理
    • 这是正确答案,接受的答案不起作用,杨的答案也不起作用。
    【解决方案4】:

    只要我的 2 美分,如果您的文件名包含空格,即“c:\My File Contains Spaces.txt”,您需要用引号将文件名括起来,否则资源管理器将假定其他词是不同的参数。 ..

    string argument = "/select, \"" + filePath +"\"";
    

    【讨论】:

    • 实际上,不,你没有。 @Samuel Yang 的示例适用于带空格的路径(已测试 Win7)
    • 阅读下面 Phil Hustwick 的回答,了解为什么你应该加上引号
    【解决方案5】:

    explorer.exe 上使用 Process.Start/select 参数奇怪地只适用于长度小于 120 个字符的路径。

    我必须使用原生 windows 方法才能让它在所有情况下都能正常工作:

    [DllImport("shell32.dll", SetLastError = true)]
    public static extern int SHOpenFolderAndSelectItems(IntPtr pidlFolder, uint cidl, [In, MarshalAs(UnmanagedType.LPArray)] IntPtr[] apidl, uint dwFlags);
    
    [DllImport("shell32.dll", SetLastError = true)]
    public static extern void SHParseDisplayName([MarshalAs(UnmanagedType.LPWStr)] string name, IntPtr bindingContext, [Out] out IntPtr pidl, uint sfgaoIn, [Out] out uint psfgaoOut);
    
    public static void OpenFolderAndSelectItem(string folderPath, string file)
    {
        IntPtr nativeFolder;
        uint psfgaoOut;
        SHParseDisplayName(folderPath, IntPtr.Zero, out nativeFolder, 0, out psfgaoOut);
    
        if (nativeFolder == IntPtr.Zero)
        {
            // Log error, can't find folder
            return;
        }
    
        IntPtr nativeFile;
        SHParseDisplayName(Path.Combine(folderPath, file), IntPtr.Zero, out nativeFile, 0, out psfgaoOut);
    
        IntPtr[] fileArray;
        if (nativeFile == IntPtr.Zero)
        {
            // Open the folder without the file selected if we can't find the file
            fileArray = new IntPtr[0];
        }
        else
        {
            fileArray = new IntPtr[] { nativeFile };
        }
    
        SHOpenFolderAndSelectItems(nativeFolder, (uint)fileArray.Length, fileArray, 0);
    
        Marshal.FreeCoTaskMem(nativeFolder);
        if (nativeFile != IntPtr.Zero)
        {
            Marshal.FreeCoTaskMem(nativeFile);
        }
    }
    

    【讨论】:

    • 这帮助我重用了一个文件夹。 Process.Start("explorer.exe", "/select xxx") 每次都会打开一个新文件夹!
    • 应该这样做,我也会为 sfgao 创建一个标志,并传递该枚举而不是 uint
    • 虽然有一个小问题,但它可以工作;第一次打开文件夹时,它不会突出显示。我在按钮单击方法中调用它,一旦文件夹打开,如果我再次单击按钮,它就会突出显示选定的文件/文件夹。可能是什么问题?
    • 这是唯一符合专业软件“在资源管理器中显示”功能的解决方案。 (1) 重用同一个资源管理器进程。 (2) 尽可能重复使用相同的窗口。
    【解决方案6】:

    Samuel Yang 的回答让我大跌眼镜,这是我的 3 美分。

    Adrian Hum 是对的,请确保在文件名周围加上引号。不是因为它不能像 zourtney 指出的那样处理空格,而是因为它将文件名中的逗号(可能还有其他字符)识别为单独的参数。 所以它应该看起来像 Adrian Hum 建议的那样。

    string argument = "/select, \"" + filePath +"\"";
    

    【讨论】:

    • 并确保filePath 中不包含"。这个字符在 Windows 系统上显然是非法的,但在所有其他系统上都是允许的(例如,POSIXish 系统),所以如果你想要可移植性,你需要更多的代码。
    【解决方案7】:

    使用“/select,c:\file.txt”

    注意 /select 后面应该有一个逗号而不是空格..

    【讨论】:

      【解决方案8】:

      找不到文件的最可能原因是路径中有空格。例如,它不会找到“explorer /select,c:\space space\space.txt”。

      只要在路径前后加双引号,比如;

      explorer /select,"c:\space space\space.txt"
      

      或在 C# 中使用

      System.Diagnostics.Process.Start("explorer.exe","/select,\"c:\space space\space.txt\"");
      

      【讨论】:

        【解决方案9】:

        您需要将要传递的参数(“/select 等”)放在 Start 方法的第二个参数中。

        【讨论】:

          【解决方案10】:
          string windir = Environment.GetEnvironmentVariable("windir");
          if (string.IsNullOrEmpty(windir.Trim())) {
              windir = "C:\\Windows\\";
          }
          if (!windir.EndsWith("\\")) {
              windir += "\\";
          }    
          
          FileInfo fileToLocate = null;
          fileToLocate = new FileInfo("C:\\Temp\\myfile.txt");
          
          ProcessStartInfo pi = new ProcessStartInfo(windir + "explorer.exe");
          pi.Arguments = "/select, \"" + fileToLocate.FullName + "\"";
          pi.WindowStyle = ProcessWindowStyle.Normal;
          pi.WorkingDirectory = windir;
          
          //Start Process
          Process.Start(pi)
          

          【讨论】:

            【解决方案11】:

            这可能有点矫枉过正,但我​​喜欢方便的功能,所以拿这个吧:

                public static void ShowFileInExplorer(FileInfo file) {
                    StartProcess("explorer.exe", null, "/select, "+file.FullName.Quote());
                }
                public static Process StartProcess(FileInfo file, params string[] args) => StartProcess(file.FullName, file.DirectoryName, args);
                public static Process StartProcess(string file, string workDir = null, params string[] args) {
                    ProcessStartInfo proc = new ProcessStartInfo();
                    proc.FileName = file;
                    proc.Arguments = string.Join(" ", args);
                    Logger.Debug(proc.FileName, proc.Arguments); // Replace with your logging function
                    if (workDir != null) {
                        proc.WorkingDirectory = workDir;
                        Logger.Debug("WorkingDirectory:", proc.WorkingDirectory); // Replace with your logging function
                    }
                    return Process.Start(proc);
                }
            

            这是我用作 .Quote() 的扩展函数:

            static class Extensions
            {
                public static string Quote(this string text)
                {
                    return SurroundWith(text, "\"");
                }
                public static string SurroundWith(this string text, string surrounds)
                {
                    return surrounds + text + surrounds;
                }
            }
            

            【讨论】:

              猜你喜欢
              • 2012-05-05
              • 1970-01-01
              • 1970-01-01
              • 2013-08-11
              • 1970-01-01
              • 1970-01-01
              • 2014-06-25
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多