Programmatically select multiple files in windows explorer

前端 未结 8 1982
粉色の甜心
粉色の甜心 2020-11-28 11:01

I can display and select a single file in windows explorer like this:

explorer.exe /select, "c:\\path\\to\\file.txt"

However, I can

相关标签:
8条回答
  • 2020-11-28 11:37

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

    0 讨论(0)
  • 2020-11-28 11:39

    This should be possible with the shell function SHOpenFolderAndSelectItems

    EDIT

    Here is some sample code showing how to use the function in C/C++, without error 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
    ILFree(dir);
    ILFree(item1);
    ILFree(item2);
    
    0 讨论(0)
  • 2020-11-28 11:39

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

    0 讨论(0)
  • 2020-11-28 11:49

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

    Unmanaged code looks like this (compiled from China code posts 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);
    
        [ComImport]
        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        [Guid("000214F9-0000-0000-C000-000000000046")]
        public interface IShellLinkW
        {
            [PreserveSig]
            int GetPath(StringBuilder pszFile, int cch, [In, Out] ref WIN32_FIND_DATAW pfd, uint fFlags);
    
            [PreserveSig]
            int GetIDList([Out] out IntPtr ppidl);
    
            [PreserveSig]
            int SetIDList([In] ref IntPtr pidl);
    
            [PreserveSig]
            int GetDescription(StringBuilder pszName, int cch);
    
            [PreserveSig]
            int SetDescription([MarshalAs(UnmanagedType.LPWStr)] string pszName);
    
            [PreserveSig]
            int GetWorkingDirectory(StringBuilder pszDir, int cch);
    
            [PreserveSig]
            int SetWorkingDirectory([MarshalAs(UnmanagedType.LPWStr)] string pszDir);
    
            [PreserveSig]
            int GetArguments(StringBuilder pszArgs, int cch);
    
            [PreserveSig]
            int SetArguments([MarshalAs(UnmanagedType.LPWStr)] string pszArgs);
    
            [PreserveSig]
            int GetHotkey([Out] out ushort pwHotkey);
    
            [PreserveSig]
            int SetHotkey(ushort wHotkey);
    
            [PreserveSig]
            int GetShowCmd([Out] out int piShowCmd);
    
            [PreserveSig]
            int SetShowCmd(int iShowCmd);
    
            [PreserveSig]
            int GetIconLocation(StringBuilder pszIconPath, int cch, [Out] out int piIcon);
    
            [PreserveSig]
            int SetIconLocation([MarshalAs(UnmanagedType.LPWStr)] string pszIconPath, int iIcon);
    
            [PreserveSig]
            int SetRelativePath([MarshalAs(UnmanagedType.LPWStr)] string pszPathRel, uint dwReserved);
    
            [PreserveSig]
            int Resolve(IntPtr hwnd, uint fFlags);
    
            [PreserveSig]
            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);
            ReleaseComObject(dir);
            ReleaseComObject(filesToSelectIntPtrs);
        }
    
        private static void ReleaseComObject(params object[] comObjs)
        {
            foreach (object obj in comObjs)
            {
                if (obj != null && Marshal.IsComObject(obj))
                    Marshal.ReleaseComObject(obj);
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-28 11:51

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

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

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

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

    0 讨论(0)
  • 2020-11-28 11:54

    it cannot be done through explorer.exe

    0 讨论(0)
提交回复
热议问题