23

我可以像这样在 Windows 资源管理器中显示和选择单个文件:

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

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

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

https://support.microsoft.com/kb/314853
http://web.archive.org/web/20100716112458/http://www.infocellar.com:80/Win98/explorer-switches.htm

4

8 回答 8

19

这应该可以通过 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);
于 2010-06-10T02:36:47.240 回答
8

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

非托管代码看起来像这样(从中国代码帖子编译并修复其错误)

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);
        }
    }
}
于 2010-08-26T15:02:26.137 回答
2

无法通过 explorer.exe 完成

于 2008-08-13T00:47:43.337 回答
2

根据您实际想要完成的任务,您可以使用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# 中的自动热键。您可以将自动热键脚本制作成可以由您的 C# 应用程序启动的独立可执行文件(大约 400k)(就像您启动资源管理器的方式一样)。您也可以将命令行参数传递给它。它没有任何运行时要求。

于 2008-08-13T05:56:33.527 回答
1

这是考虑您要实现的目标以及是否有更好的方法可能会很好的问题之一。

添加更多上下文 - 我们公司开发了一个 C# 客户端应用程序,它允许用户加载文件并对其进行处理,有点像 iTunes 如何管理您的 MP3 文件而不向您显示磁盘上的实际文件。

在应用程序中选择一个文件并执行“在 Windows 资源管理器中显示此文件”命令很有用 - 这就是我想要实现的目标,并且已经为单个文件这样做了。

我们有一个 ListView,它允许用户在应用程序中选择多个文件,并移动/删除/等它们。让这个“在 Windows 中显示这个文件”命令适用于多个选定文件会很好 - 至少如果所有源文件都在同一个目录中,但如果不可能,那么它不是主要功能。

于 2008-08-17T20:52:22.750 回答
0

我想您可以使用FindWindowEx获取 Windows Explorer 的 SysListView32,然后使用SendMessagewithLVM_SETITEMSTATE选择项目。难点是要知道物品的位置……或许LVM_FINDITEM可以用这个。

于 2008-10-24T11:17:33.477 回答
0

Grr 我也想这样做。当您选择 2+ 个文件并右键单击并执行“打开文件位置”时,媒体播放器会执行此操作,但不确定如何(我也不想花时间与 procmon 一起弄清楚)。

于 2008-12-03T23:48:47.657 回答
0

有 COM 自动化 LateBinding IDispatch 接口,这些接口很容易从 PowerShell、Visual Basic.NET 和 C# 中使用,一些示例代码:

$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
            Next
        Next
    End Sub
End Class

https://docs.microsoft.com/en-us/windows/win32/shell/shellfolderview-selectitem

于 2019-12-29T05:51:52.707 回答