在资源管理器中打开一个文件夹并选择一个文件


150

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

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

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

如何在C#中执行此命令?

Answers:



327
// 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);

1
这是显著我:)它不仅打开了目录,但选择的特定文件以及:)谢谢问候
InfantPro'Aravind”

2
它的工作原理就像一个咒语,但是任何Idea我们如何才能对多个文件进行处理?
Pankaj 2012年

7
请注意,如果我的文件路径使用正斜杠,那么带有文件路径的/ select参数似乎对我不起作用。因此,我必须要做filePath = filePath.Replace('/','\\');
维克托·谢拉鲁

6
如在其他地方提到的,您的路径应包含在引号中-这样可以防止包含逗号的目录或文件名出现问题。
卡加纳尔

4
我正在努力解决这个问题,有时上述方法不起作用,因为该文件包含逗号。如果我读过卡加纳尔的评论,那将节省我一个小时的工作。我敦促Samuel Yang将上面的代码修改为:字符串参数= @“ / select” +“ \”“ + filePath +” \“”
韦恩·卢

34

如果您的路径包含逗号,则在使用Process.Start(ProcessStartInfo)时可以在路径两边加上引号。

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

这是一个对我有用的简单示例。

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);

这应该是公认的答案。它只是缺乏对各种可能的故障(正确的问题,错误的路径等)的适当异常处理
AFract

这是正确的答案,接受的答案不起作用,杨的答案也不起作用。
VK

31

如果我的文件名中包含空格,即“ c:\ My File Contains Spaces.txt”,则仅值2美分,您需要在文件名中加上引号,否则资源管理器会假设其他单词是不同的参数...

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

4
实际上,不,你不知道。@Samuel Yang的示例适用于带有空格的路径(经过Win7测试)
Courtney Christensen

8
菲尔Hustwick阅读下面的答案为什么你应该把引号不过
AKKU

18

塞缪尔·杨(Samuel Yang)的回答使我绊倒了,这是我3美分的价值。

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

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

1
并确保其中filePath不含"。在Windows系统上,此字符显然是非法的,但在所有其他系统(例如POSIXish系统)上都是允许的,因此,如果要移植,则需要更多代码。
宾基

14

将该参数与Process.Starton explorer.exe一起使用/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”)每次都会打开一个新文件夹!
米特金斯

这就是应该怎么做,我也将为sf​​gao创建一个标志,并传递该枚举而不是uint
L.Trabacchin

尽管有一个小问题,但这仍然有效。第一次打开文件夹时,它不会突出显示。我在按钮单击方法内部调用此方法,如果再次单击该按钮,则打开文件夹后,它将突出显示所选的文件/文件夹。可能是什么问题呢?
萨克

13

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

请注意,/ select后应有一个逗号而不是空格。


6

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


5
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)

5

找不到文件的最可能原因是路径中有空格。例如,它将找不到“ 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\"");

1

可能有点过大,但是我喜欢便捷功能,因此请选择以下功能:

    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);
    }

这是我用作<string> .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;
    }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.