Programmatically selecting file in explorer
Asked Answered
L

3

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.

Lucilius answered 9/6, 2010 at 22:0 Comment(3)
I'm not seeing this behavior on Windows 7 x64. Two windows are opening correctly, each with the correct file selected.Vigilance
You are right, the behavior on Vista and Win 7 is different. I've updated my question to mention this.Lucilius
#4831601 and #8182994 seem related...Pictish
L
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);
    }
}
Lucilius answered 10/6, 2010 at 0:15 Comment(4)
appears chromium uses this, as well, see src.chromium.org/svn/trunk/src/chrome/browser/…Pictish
Here's a binary compiled version people can call out to (for those averse to COM): gist.github.com/rdp/9748303Pictish
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.Kalikalian
In case it is useful to someone, posted a related question yesterday on how to use SHOpenFolderandSelectItems() with an array of items. #47564692Unstoppable
L
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.

Larrylars answered 5/12, 2011 at 19:7 Comment(1)
SHOpenFolderAndSelectItems for me fails unless I use a perfectly formatted full path, like c:\devPictish
O
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.

Ophthalmoscopy answered 9/6, 2010 at 22:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.