176

I'm trying to open a folder in explorer with a file selected.

The following code produces a file not found exception:

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

How can I get this command to execute in C#?

RandomEngy
  • 14,931
  • 5
  • 70
  • 113
Michael L
  • 5,560
  • 7
  • 29
  • 32

12 Answers12

393
// 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);
Winter
  • 3,894
  • 7
  • 24
  • 56
Samuel Yang
  • 3,939
  • 2
  • 16
  • 2
  • 1
    it was significant for me :) it not only opened the directory but selected the particular file as well :) thanks regards – Rookie Programmer Aravind Jul 28 '11 at 11:58
  • 2
    It works like a charm but any Idea how can we do that for multiple files ? – Pankaj Dec 26 '12 at 22:17
  • 8
    Small note, the /select argument with file path doesn't seem to work for me if my file path uses forward slashes. Therefore I have to do filePath = filePath.Replace('/', '\\'); – Victor Chelaru Jan 29 '13 at 18:48
  • 7
    As mentioned elsewhere, your path should be contained in quotes -- this prevents problems with directory or file names that contain commas. – Kaganar Sep 12 '13 at 16:48
  • 4
    I was battling on the issue sometimes the above approach did not work because the file contains a comma. If I had read Kaganar's comment, it would have saved me a hour of work. I urge Samuel Yang to modify above code to: string argument=@"/select"+"\"" + filePath+"\"" – Wayne Lo Jan 06 '16 at 19:12
  • This is the most accurate response, and should be marked as the answer for this question. – Fabricio Aug 01 '17 at 21:49
  • even though this works, it sometimes does not select the files (first time mostly, as reported here: https://stackoverflow.com/q/22578757). I ended up using code from the following answer which manages the Shell API and supports multiple file selection: https://stackoverflow.com/a/3578581 – Demo Apr 16 '19 at 10:48
  • Maybe it was just me, BUT the comma after the /select is required so "/select," otherwise it doesn't work as expected. If it is just me, does that mean I was the only one who didn't copy paste? – LordWabbit Jun 11 '20 at 10:10
49

If your path contains comma's, putting quotes around the path will work when using Process.Start(ProcessStartInfo).

It will NOT work when using Process.Start(string, string) however. It seems like Process.Start(string, string) actually removes the quotes inside of your args.

Here is a simple example that works for me.

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);
Jan Croonen
  • 640
  • 6
  • 6
  • This should be the accepted answer. It just lacks a proper exception handling for various possible failures (rights issue, wrong path, etc) – AFract Aug 25 '15 at 17:54
  • 1
    This is the right answer, the accepted answer does not work, Yang's answer also does not work. – V K Nov 09 '17 at 13:37
  • Please note that if the file is already selected in an explorer window, running this code will not open a new explorer window. It will use the existing window and selected the file. – Silent Sojourner Feb 05 '23 at 03:39
44

Use this method:

Process.Start(String, String)

First argument is an application (explorer.exe), second method argument are arguments of the application you run.

For example:

in CMD:

explorer.exe -p

in C#:

Process.Start("explorer.exe", "-p")
Bonnev
  • 947
  • 2
  • 9
  • 29
Tom Smykowski
  • 25,487
  • 54
  • 159
  • 236
33

Just my 2 cents worth, if your filename contains spaces, ie "c:\My File Contains Spaces.txt", you'll need to surround the filename with quotes otherwise explorer will assume that the othe words are different arguments...

string argument = "/select, \"" + filePath +"\"";
Adrian Hum
  • 331
  • 3
  • 2
24

Using Process.Start on explorer.exe with the /select argument oddly only works for paths less than 120 characters long.

I had to use a native windows method to get it to work in all cases:

[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);
    }
}
RandomEngy
  • 14,931
  • 5
  • 70
  • 113
  • This helped me re-use one folder. Process.Start("explorer.exe", "/select xxx") opens a new folder every time! – Mitkins Nov 27 '16 at 23:23
  • 2
    this is how it should be done, i would also create an flag for sfgao, and pass that enum instead of uint – L.Trabacchin Sep 14 '17 at 10:00
  • This works although with a small problem; the first time the folder is open it's not highlighted. I call this inside a button click method, and once the folder is open if I click the button again, then it highlights the selected file/folder. What could be the problem? – Sach Oct 03 '17 at 18:45
  • This is the only solution that is consistent with professional software's "show in Explorer" functionality. (1) Re-use the same explorer process. (2) Re-use the same window whereas possible. – Meow Cat 2012 Oct 16 '21 at 04:00
18

Samuel Yang answer tripped me up, here is my 3 cents worth.

Adrian Hum is right, make sure you put quotes around your filename. Not because it can't handle spaces as zourtney pointed out, but because it will recognize the commas (and possibly other characters) in filenames as separate arguments. So it should look as Adrian Hum suggested.

string argument = "/select, \"" + filePath +"\"";
BobWinters
  • 180
  • 1
  • 5
  • 1
    And be sure to ensure that `filePath` doesn’t contain `"` in it. This character is apparently illegal on Windows systems but allowed on all others (e.g., POSIXish systems), so you need even more code if you want portability. – binki Nov 14 '18 at 16:35
14

Use "/select,c:\file.txt"

Notice there should be a comma after /select instead of space..

9

The most possible reason for it not to find the file is the path having spaces in. For example, it won't find "explorer /select,c:\space space\space.txt".

Just add double quotes before and after the path, like;

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

or do the same in C# with

System.Diagnostics.Process.Start("explorer.exe","/select,\"c:\space space\space.txt\"");
Zztri
  • 91
  • 1
  • 1
6

You need to put the arguments to pass ("/select etc") in the second parameter of the Start method.

Paul
  • 3,125
  • 2
  • 24
  • 21
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)
Matt Fenwick
  • 48,199
  • 22
  • 128
  • 192
Corey
  • 51
  • 1
  • 1
3

It might be a bit of a overkill but I like convinience functions so take this one:

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

This is the extension function I use as <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;
    }
}
Bluescream
  • 261
  • 1
  • 8
2

Simple C# 9.0 method based on Jan Croonen's answer:

private static void SelectFileInExplorer(string filePath)
{
    Process.Start(new ProcessStartInfo()
    {
        FileName = "explorer.exe",
        Arguments = @$"/select, ""{filePath}"""
    });
}
MensSana
  • 521
  • 1
  • 5
  • 16