Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I set an existing Explorer.exe instance to select a file?

Tags:

c#

I can easily get Explorer to open up and select a file using the following :

string argument = @"/select, " + filePath;
System.Diagnostics.Process.Start("explorer.exe", argument);

However when I come to opening up the next file, I will get a new instance of explorer. This could result in our users opening having hundreds of explorers open by the end of an intensive day.

How can I get it to reuse an already open explorer instance to select the file I want?

Visual Studio can do this when you right click on a tab and select Open containing folder... providing explorer is already opened at the same directory. How has it been able to do this?

like image 241
Mongus Pong Avatar asked Nov 18 '11 12:11

Mongus Pong


Video Answer


2 Answers

How about embedding the Explorer window into your application by using the ExplorerBrowser object? That way, you can just keep reusing the window by calling IExplorerBrowser::BrowseToObject on a different folder when you want to show a different folder.

Trying to renavigate an existing Explorer window is problematic because you don't know what the user did with that window while you weren't looking. Maybe they used the Folder pane to go to some other folder, and then boom you just ripped that folder out from under them and sent it somewhere else. Or maybe they closed it! Opening a new Explorer window is a fire-and-forget type of thing. If you want to retain control of the window, then you need to exercise more explicit control (e.g. via ExplorerBrowser above).

like image 129
Raymond Chen Avatar answered Oct 24 '22 06:10

Raymond Chen


A bit late to the party, but if you want to select one or more files in a folder that already opened in an explorer window, you can do so with the shell32 method SHOpenFolderAndSelectItems. That method re-uses an existing window if there's one, or opens a new one otherwise.

[DllImport("shell32.dll")]
private static extern int SHOpenFolderAndSelectItems(IntPtr pidlFolder, uint cidl, [MarshalAs(UnmanagedType.LPArray)] IntPtr[] apidl, uint dwFlags);

[DllImport("shell32.dll")]
private static extern void SHParseDisplayName([MarshalAs(UnmanagedType.LPWStr)] string name, IntPtr bindingContext, out IntPtr pidl, uint sfgaoIn, out uint psfgaoOut);

public static void ShowFileInExplorer(string folderPath, string filePath)
{
    Shell32.SHParseDisplayName(Path.GetFullPath(folderPath), IntPtr.Zero, out IntPtr folder, 0, out uint psfgaoOut);

    if (folder == IntPtr.Zero)
    {
        return;
    }

    Shell32.SHParseDisplayName(Path.GetFullPath(filePath), IntPtr.Zero, out IntPtr file, 0, out psfgaoOut);

    if (file != IntPtr.Zero)
    {
        IntPtr[] files = { file };

        Shell32.SHOpenFolderAndSelectItems(folder, (uint)files.Length, files, 0);
        Marshal.FreeCoTaskMem(file);
    }

    Marshal.FreeCoTaskMem(folder);
}

This sample only selects one file, but can easily be extended to select multiple files.

like image 28
Domi Avatar answered Oct 24 '22 08:10

Domi