[ACCEPTED]-Programmatically select multiple files in windows explorer-windows-shell

Accepted answer
Score: 18

This should be possible with the shell function 3 SHOpenFolderAndSelectItems


Here is some sample code showing how to 2 use the function in C/C++, without error 1 checking:

//Directory to open
ITEMIDLIST *dir = ILCreateFromPath(_T("C:\\"));

//Items in directory to select
ITEMIDLIST *item1 = ILCreateFromPath(_T("C:\\Program Files\\"));
ITEMIDLIST *item2 = ILCreateFromPath(_T("C:\\Windows\\"));
const ITEMIDLIST* selection[] = {item1,item2};
UINT count = sizeof(selection) / sizeof(ITEMIDLIST);

//Perform selection
SHOpenFolderAndSelectItems(dir, count, selection, 0);

//Free resources
Score: 8

The true way of selecting multiple files 3 in Explorer is the next

Unmanaged code looks 2 like this (compiled from China code posts 1 with fixing its bugs)

static class NativeMethods
    [DllImport("shell32.dll", ExactSpelling = true)]
    public static extern int SHOpenFolderAndSelectItems(
        IntPtr pidlFolder,
        uint cidl,
        [In, MarshalAs(UnmanagedType.LPArray)] IntPtr[] apidl,
        uint dwFlags);

    [DllImport("shell32.dll", CharSet = CharSet.Auto)]
    public static extern IntPtr ILCreateFromPath([MarshalAs(UnmanagedType.LPTStr)] string pszPath);

    public interface IShellLinkW
        int GetPath(StringBuilder pszFile, int cch, [In, Out] ref WIN32_FIND_DATAW pfd, uint fFlags);

        int GetIDList([Out] out IntPtr ppidl);

        int SetIDList([In] ref IntPtr pidl);

        int GetDescription(StringBuilder pszName, int cch);

        int SetDescription([MarshalAs(UnmanagedType.LPWStr)] string pszName);

        int GetWorkingDirectory(StringBuilder pszDir, int cch);

        int SetWorkingDirectory([MarshalAs(UnmanagedType.LPWStr)] string pszDir);

        int GetArguments(StringBuilder pszArgs, int cch);

        int SetArguments([MarshalAs(UnmanagedType.LPWStr)] string pszArgs);

        int GetHotkey([Out] out ushort pwHotkey);

        int SetHotkey(ushort wHotkey);

        int GetShowCmd([Out] out int piShowCmd);

        int SetShowCmd(int iShowCmd);

        int GetIconLocation(StringBuilder pszIconPath, int cch, [Out] out int piIcon);

        int SetIconLocation([MarshalAs(UnmanagedType.LPWStr)] string pszIconPath, int iIcon);

        int SetRelativePath([MarshalAs(UnmanagedType.LPWStr)] string pszPathRel, uint dwReserved);

        int Resolve(IntPtr hwnd, uint fFlags);

        int SetPath([MarshalAs(UnmanagedType.LPWStr)] string pszFile);

    [Serializable, StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode), BestFitMapping(false)]
    public struct WIN32_FIND_DATAW
        public uint dwFileAttributes;
        public FILETIME ftCreationTime;
        public FILETIME ftLastAccessTime;
        public FILETIME ftLastWriteTime;
        public uint nFileSizeHigh;
        public uint nFileSizeLow;
        public uint dwReserved0;
        public uint dwReserved1;

        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
        public string cFileName;

        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
        public string cAlternateFileName;

    public static void OpenFolderAndSelectFiles(string folder, params string[] filesToSelect)
        IntPtr dir = ILCreateFromPath(folder);

        var filesToSelectIntPtrs = new IntPtr[filesToSelect.Length];
        for (int i = 0; i < filesToSelect.Length; i++)
            filesToSelectIntPtrs[i] = ILCreateFromPath(filesToSelect[i]);

        SHOpenFolderAndSelectItems(dir, (uint) filesToSelect.Length, filesToSelectIntPtrs, 0);

    private static void ReleaseComObject(params object[] comObjs)
        foreach (object obj in comObjs)
            if (obj != null && Marshal.IsComObject(obj))
Score: 2

it cannot be done through explorer.exe


Score: 2

Depending on what you actually want to accomplish 18 you may be able to do it with AutoHotKey. It is an 17 amazing free tool for automating things 16 you normally can't do. It should come with 15 Windows. This script will select your file 14 and highlight the next two files below it 13 when you hit F12.

 run explorer.exe /select`, "c:\path\to\file.txt"
 SendInput {Shift Down}{Down}{Down}{Shift Up}

It is also possible to 12 just put those two middle lines in a text 11 file and then pass it is a parm to autohotkey.exe. They 10 have an option to compile the script also, which 9 would make it a standalone exe that you 8 could call. Works great with a great help 7 file.

@Orion, It is possible to use autohotkey 6 from C#. You can make an autohotkey script 5 into a standalone executable (about 400k) that 4 can be launched by your C# app (just the 3 way you are launching explorer). You can 2 also pass it command line parameters. It 1 does not have any runtime requirements.

Score: 2

There are COM Automation LateBinding IDispatch 2 interfaces, these are easy to use from PowerShell, Visual 1 Basic.NET and C#, some sample code:

$shell = New-Object -ComObject Shell.Application

function SelectFiles($filesToSelect)
    foreach ($fileToSelect in $filesToSelect)
        foreach ($window in $shell.Windows())
            foreach ($folderItem in $window.Document.Folder.Items())
                if ($folderItem.Path -eq $fileToSelect)
                    $window.Document.SelectItem($folderItem, 1 + 8)


Option Strict Off

Imports Microsoft.VisualBasic

Public Class ExplorerHelp
    Shared ShellApp As Object = CreateObject("Shell.Application")

    Shared Sub SelectFile(filepath As String)
        For Each i In ShellApp.Windows
            For Each i2 In i.Document.Folder.Items()
                If i2.Path = filepath Then
                    i.Document.SelectItem(i2, 1 + 8)
                    Exit Sub
                End If
    End Sub
End Class


Score: 1

This is one of those questions where it 20 may be good to consider what you're trying 19 to achieve, and whether there's a better 18 method.

To add some more context - Our company 17 develops a C# client application, which 16 allows users to load files and do stuff 15 with them, kind of like how iTunes manages 14 your MP3 files without showing you the actual 13 file on disk.

It's useful to select a file 12 in the application, and do a 'Show me this 11 file in Windows Explorer` command - this 10 is what I'm trying to achieve, and have 9 done so for single files.

We have a ListView 8 which allows users to select multiple files 7 within the application, and move/delete/etc 6 them. It would be nice to have this 'show 5 me this file in windows' command work for 4 multiple selected files - at least if all 3 the source files are in the same directory, but 2 if it's not possible then it's not a major 1 feature.

Score: 0

I suppose you can use FindWindowEx to get the SysListView32 4 of Windows Explorer, then use SendMessage with LVM_SETITEMSTATE to 3 select the items. The difficulty being to 2 know the position of the items... Perhaps 1 LVM_FINDITEM can be used for this.

Score: 0

Grr i would like to do this as well. Media 5 Player does it when you select 2+ files 4 and right click and do "open file location" but 3 not exactly sure how (nor do i really feel 2 like spending the time w/ procmon to figure 1 it out).

More Related questions