62

I would like to code a function to which you can pass a file path, for example:

C:\FOLDER\SUBFOLDER\FILE.TXT

and it would open Windows Explorer with the folder containing the file and then select this file inside the folder. (Similar to the "Show In Folder" concept used in many programs.)

How can I do this?

Helen
  • 58,317
  • 8
  • 161
  • 218
Jester
  • 2,682
  • 5
  • 27
  • 40
  • Also, is it possible to select multiple files? – Colonel Panic Apr 08 '15 at 10:22
  • Possible duplicate of [Implement "Open Containing Folder" and highlight file](http://stackoverflow.com/questions/2829501/implement-open-containing-folder-and-highlight-file) – RandomEngy Sep 10 '16 at 15:00
  • Possible duplicate of [Opening a folder in explorer and selecting a file](https://stackoverflow.com/q/334630/11585798) – mekb Jan 19 '20 at 11:44

4 Answers4

142

Easiest way without using Win32 shell functions is to simply launch explorer.exe with the /select parameter. For example, launching the process

explorer.exe /select,"C:\Folder\subfolder\file.txt"

will open a new explorer window to C:\Folder\subfolder with file.txt selected.

If you wish to do it programmatically without launching a new process, you'll need to use the shell function SHOpenFolderAndSelectItems, which is what the /select command to explorer.exe will use internally. Note that this requires the use of PIDLs, and can be a real PITA if you are not familiar with how the shell APIs work.

Here's a complete, programmatic implementation of the /select approach, with path cleanup thanks to suggestions from @Bhushan and @tehDorf:

public bool ExploreFile(string filePath) {
    if (!System.IO.File.Exists(filePath)) {
        return false;
    }
    //Clean up file path so it can be navigated OK
    filePath = System.IO.Path.GetFullPath(filePath);
    System.Diagnostics.Process.Start("explorer.exe", string.Format("/select,\"{0}\"", filePath));
    return true;
}

Reference: Explorer.exe Command-line switches

zwcloud
  • 3,527
  • 3
  • 24
  • 53
Mahmoud Al-Qudsi
  • 26,006
  • 12
  • 71
  • 118
  • 3
    You need a comma after the select like this explorer.exe /select, "c:\folder\subfolder\file.txt – Justin Harvey Dec 03 '12 at 09:40
  • What are the downsides of launching a new process? – Gusdor Sep 17 '15 at 10:19
  • @Gusdor Nothing, really. Unless you have enabled launched folder windows in a separate process in your folder view options (by default, it's disabled) this does not actually launch a new process. It goes through the motions, but an existing explorer.exe instance will be called to handle the request instead of launching a new process in a separate memory space. If you're calling this code a lot, it's certainly more efficient and less wasteful to use `SHOpenFolderAndSelectItems` during the opening sequence, though. – Mahmoud Al-Qudsi Nov 25 '15 at 19:25
  • 2
    @MahmoudAl-Qudsi Instead of using a `Regex` to clean up the file path, you can use `filePath = System.IO.Path.GetFullPath(filePath);`. It will normalize the directory separators and it will also resolve relative paths, such as if you pass in something like `@"..\some\relative\file\path.txt"` or `@"C:\Some\relative\..\file\path.txt"`. You could also update the example to use the new string interpolation: `Process.Start("explorer.exe", $"/select,\"{filePath}\"");` – tehDorf May 12 '17 at 22:50
  • This doesn't seem to work if the filename itself contains a coma. – Joan Charmant Oct 25 '19 at 14:44
5

The supported method since Windows XP (i.e. not supported on Windows 2000 or earlier) is SHOpenFolderAndSelectItems:

void OpenFolderAndSelectItem(String filename)
{
   // Parse the full filename into a pidl
   PIDLIST_ABSOLUTE pidl;
   SFGAO flags;
   SHParseDisplayName(filename, null, out pidl, 0, out flags);
   try 
   {
      // Open Explorer and select the thing
      SHOpenFolderAndSelectItems(pidl, 0, null, 0);
   }
   finally 
   {
      // Use the task allocator to free to returned pidl
      CoTaskMemFree(pidl);
   }
}
Ian Boyd
  • 220,884
  • 228
  • 805
  • 1,125
4

When executing the command if your path contains multiple slashes then it will not open the folder and select the file properly Please make sure that your file path should be like this

C:\a\b\x.txt

instead of

C:\\a\\b\\x.txt

Bhushan Pawar
  • 441
  • 4
  • 12
0

To follow up on @Mahmoud Al-Qudsi's answer. when he says "launching the process", this is what worked for me:

// assume variable "path" has the full path to the file, but possibly with / delimiters
for ( int i = 0 ; path[ i ] != 0 ; i++ )
{
    if ( path[ i ] == '/' )
    {
        path[ i ] = '\\';
    }
}
std::string s = "explorer.exe /select,\"";
s += path;
s += "\"";
PROCESS_INFORMATION processInformation;
STARTUPINFOA startupInfo;
ZeroMemory( &startupInfo, sizeof(startupInfo) );
startupInfo.cb = sizeof( STARTUPINFOA );
ZeroMemory( &processInformation, sizeof( processInformation ) );
CreateProcessA( NULL, (LPSTR)s.c_str(), NULL, NULL, FALSE, 0, NULL, NULL, &startupInfo, &processInformation );
M Katz
  • 4,604
  • 3
  • 36
  • 59