在Windows资源管理器中以编程方式选择多个文件

时间:2020-03-05 18:39:18  来源:igfitidea点击:

我可以在Windows资源管理器中显示并选择一个文件,如下所示:

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

但是,我不知道如何选择多个文件。我尝试过的select的排列都没有。

注意:我在这些页面上查看了文档,但都没有帮助。

https://support.microsoft.com/kb/314853
http://www.infocellar.com/Win98/explorer-switches.htm

解决方案

回答

它无法通过explorer.exe完成

回答

根据我们实际想要完成的工作,我们可以使用AutoHotKey来完成此操作。这是一个很棒的免费工具,可以自动执行通常无法执行的操作。它应该随Windows一起提供。按下F12键时,此脚本将选择文件并突出显示其下面的下两个文件。

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

也可以仅将这两个中间行放在文本文件中,然后将其作为参数传递给autohotkey.exe。他们还可以选择编译脚本,这将使它成为我们可以调用的独立exe。很好的帮助文件,效果很好。

@Orion,可以使用C#中的autohotkey。我们可以将自动热键脚本制作成独立的可执行文件(约400k),该可执行文件可以由Capp启动(就像启动资源管理器的方式一样)。我们也可以将命令行参数传递给它。它没有任何运行时要求。

回答

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

添加更多上下文
我们公司开发了一个Cclient应用程序,该应用程序允许用户加载文件并对其进行处理,就像iTunes如何管理MP3文件而不显示磁盘上的实际文件一样。

在应用程序中选择一个文件,然后执行"在Windows资源管理器中显示此文件"命令,这是我要达到的目的,并且已经针对单个文件执行了此操作。

我们有一个ListView,它允许用户在应用程序中选择多个文件,然后移动/删除/等它们。至少在所有源文件都在同一目录中的情况下,最好使此"在Windows中向我显示此文件"命令对多个选定文件有效,但是如果不可能,则这不是主要功能。

回答

我想我们可以使用" FindWindowEx"来获取Windows资源管理器的SysListView32,然后将" SendMessage"和" LVM_SETITEMSTATE"一起使用来选择项目。困难在于知道项目的位置...也许可以使用" LVM_FINDITEM"来实现。

回答

我也想这样做。当我们选择2个以上的文件并右键单击并执行"打开文件位置"时,Media Player会执行此操作,但不能完全确定该操作的方式(我也不想花时间用procmon来弄清楚它)。

回答

可以使用shell函数SHOpenFolderAndSelectItems做到这一点。

编辑

这是一些示例代码,显示了如何在C / C ++中使用该函数,而没有进行错误检查:

//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);

回答

在资源管理器中选择多个文件的真正方法是下一个

非托管代码如下所示(从中国的代码发布中编译并修复了其错误)

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);
        }
    }
}