22

In my application I can programmatically open explorer and select a file using the following code:

void BrowseToFile(LPCTSTR filename)
{
    CString strArgs; 
    strArgs = _T("/select,\"");
    strArgs += filename; 
    strArgs += _T("\"");

    ShellExecute(0, _T("open"), _T("explorer.exe"), strArgs, 0, SW_NORMAL);
}

My problem is that if I call this function a second time with a different file, but in the same folder, the selection in explorer does not change to the new file, but remains on the previous file.

For example, if I call my function with C:\path\to\file1.txt, a new explorer window will open and file1.txt will be selected. If I call my function a second time with C:\path\to\file2.txt, the existing explorer window will be activated, but the selection will still be on file1.txt.

Is there a way to force explorer to update the selection or a better way to accomplish this?

EDIT:

The behavior mentioned above was on Windows XP. It seems the behavior on Vista / Win7 is different. Each call will open a new instance of explorer and select the file.

My main goal is to replicate the Visual Studio option to Open Containing Folder of a document. This feature in Visual Studio behaves the same on XP, Vista, and Win7. It will not create a new instance if another instance with the same folder is already open, but it will update the selection to the new file.

If anybody knows how Visual Studio accomplishes this I would love to know about it.

flashk
  • 2,451
  • 2
  • 20
  • 31
  • I'm not seeing this behavior on Windows 7 x64. Two windows are opening correctly, each with the correct file selected. – Julien Lebosquain Jun 09 '10 at 22:08
  • You are right, the behavior on Vista and Win 7 is different. I've updated my question to mention this. – flashk Jun 09 '10 at 22:32
  • http://stackoverflow.com/questions/4831101/how-to-re-use-existing-already-opened-windows-explorer-window-to-launch-explorer and http://stackoverflow.com/questions/8182494/how-can-i-set-an-existing-explorer-exe-instance-to-select-a-file seem related... – rogerdpack Jun 10 '13 at 19:42

3 Answers3

38

Found the answer to my question. I need to use the shell function SHOpenFolderAndSelectItems. Here is the code for the function if anybody is ever interested:

void BrowseToFile(LPCTSTR filename)
{
    ITEMIDLIST *pidl = ILCreateFromPath(filename);
    if(pidl) {
        SHOpenFolderAndSelectItems(pidl,0,0,0);
        ILFree(pidl);
    }
}
flashk
  • 2,451
  • 2
  • 20
  • 31
  • appears chromium uses this, as well, see http://src.chromium.org/svn/trunk/src/chrome/browser/platform_util_win.cc – rogerdpack Jun 10 '13 at 19:35
  • Here's a binary compiled version people can call out to (for those averse to COM): https://gist.github.com/rdp/9748303 – rogerdpack Mar 24 '14 at 20:24
  • 1
    Remember to call `CoInitializeEx(...)` before calling `SHOpenFolderAndSelectItems(...)`, and make sure to replace all forwardslashes in your path with backslashes. Failure to do either of these two things will result in failure. – Tim Severeijns Apr 30 '16 at 23:24
  • In case it is useful to someone, posted a related question yesterday on how to use SHOpenFolderandSelectItems() with an array of items. https://stackoverflow.com/questions/47564192/shopenfolderandselectitems-with-arrays – Stéphane Nov 30 '17 at 17:13
4

Try the '/n' option. This will, however, open a new folder - perhaps already opened. But, at least, the file you specify is selected.

/n,/select,<path_and_filename>

SHOpenFolderAndSelectItems always fails in my case and I can't figure out why. Btw, you must call CoInitialize/CoInitializeEx before calling this one.

user732592
  • 247
  • 1
  • 7
0

In the case you outlined it appears the file window only selects the file when it's initialized instead of when activated.

Although this feels like a kludge, you could detect XP and only for that OS close the dialog using its handle and open a new one to target another file with.

John K
  • 28,441
  • 31
  • 139
  • 229