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

问题描述 投票:18回答:8

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

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

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

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

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

windows explorer windows-shell
8个回答
17
投票

这在shell函数SHOpenFolderAndSelectItems中应该可行

编辑

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

SHOpenFolderAndSelectItems

6
投票

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

非托管代码看起来像这样(从中国的代码集编译并修正了其错误)

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

2
投票

无法通过explorer.exe完成


1
投票

取决于您实际想要完成的工作,您可以使用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); } } } 完成此操作。这是一个很棒的免费工具,可以自动执行通常无法执行的操作。它应该随Windows一起提供。当您按F12键时,此脚本将选择您的文件并突出显示其下面的下两个文件。

AutoHotKey

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

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


1
投票

这是其中一个问题,可以考虑您要达到的目标以及是否有更好的方法。

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

[在应用程序中选择一个文件,然后执行“在Windows资源管理器中向我显示此文件”命令-这是我正在尝试实现的功能,并且已经针对单个文件执行了此操作。

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


0
投票

我想您可以使用F12:: run explorer.exe /select`, "c:\path\to\file.txt" SendInput {Shift Down}{Down}{Down}{Shift Up} return 获取Windows资源管理器的SysListView32,然后使用FindWindowExSendMessage来选择项目。困难在于知道项目的位置...也许可以使用LVM_SETITEMSTATE


0
投票

Grr,我也想这样做。当您选择2个以上的文件并右键单击并执行“打开文件位置”时,Media Player会执行此操作,但不能完全确定该操作的方式(我也不想花时间用procmon来解决问题)。


0
投票

有COM自动化LateBinding IDispatch接口,可以从PowerShell,Visual Basic.NET和C#易于使用,有些示例代码:

LVM_FINDITEM

-

$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

© www.soinside.com 2019 - 2024. All rights reserved.