2008-08-13 8 views
17

puedo mostrar y seleccionar un único archivo en Windows Explorer como esto:programación seleccionar varios archivos en Windows Explorer

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

Sin embargo, no puedo encontrar la manera de seleccionar más de un archivo. Ninguna de las permutaciones de seleccionar He intentado funcionar.

Nota: Miré estas páginas para ver los documentos, ninguno ayudó.

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

Respuesta

16

esto debería ser posible con la función Shell SHOpenFolderAndSelectItems

EDITAR

Aquí es un código de ejemplo que muestra cómo utilizar la función en C/C++, sin comprobación de errores:

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

Cualquier información adicional sobre el uso de este método sería útil ... no parece haber nada en pinvoke.net, y no me gusta la interoperabilidad. – devios1

+0

He actualizado mi publicación para que contenga código C/C++ de muestra – flashk

+0

¡Agradable! Gracias por eso –

2

que no se puede hacer a través explorer.exe

1

Dependiendo de lo que realmente quiere lograr es posible que pueda hacerlo con AutoHotKey. Es una increíble herramienta gratuita para automatizar cosas que normalmente no puedes hacer. Debería venir con Windows. Este script seleccionará su archivo y resaltará los siguientes dos archivos debajo de él cuando presione F12.

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

También es posible que sólo hay que poner esas dos líneas medias en un archivo de texto y luego pasarlo es un Parm a autohotkey.exe. También tienen la opción de compilar el script, lo que lo convertiría en un ejecutable independiente al que podrías llamar. Funciona muy bien con un gran archivo de ayuda.

@Orion, es posible utilizar autohotkey de C#. Puede hacer que un script autohotkey se convierta en un ejecutable independiente (alrededor de 400k) que pueda lanzar su aplicación C# (solo la forma en que está ejecutando el explorador). También puede pasar sus parámetros de línea de comando. No tiene ningún requisito de tiempo de ejecución.

+0

no funcionará bien si los archivos no son una después de otra sin embargo? – Svish

+0

Es por eso que dije "dependiendo" y "puedo". Hay muchas opciones dentro de autohotkey que incluyen la automatización de una búsqueda, solo di un ejemplo. – bruceatk

+1

No estoy seguro de por qué esto está marcado hacia abajo. AutoHotkey es una excelente solución cuando necesitas hacer algo que simplemente no puedes hacer usando una API existente. Tiene muchas salvaguardas que se pueden usar para garantizar que el programa correcto sea el objetivo. Hay muchas posibilidades La respuesta que está marcada como respuesta, no es una respuesta. Es solo una declaración obvia que es la razón por la cual se formuló la pregunta en primer lugar. Yo sugeriría que cualquier persona que marque esta respuesta primero debe buscar en AutoHotkey y aprender qué puede hacer. Debería estar integrado en Windows. – bruceatk

1

Esta es una de esas preguntas en las que puede ser bueno considerar lo que está tratando de lograr y si hay un método mejor.

Para añadir un poco más de contexto - Nuestra empresa desarrolla una aplicación de cliente de C#, que permite a los usuarios cargar archivos y hacer cosas con ellos, algo así como la forma en iTunes gestiona sus archivos MP3 sin que le muestra el archivo real en el disco .

Es útil para seleccionar un archivo en la aplicación, y hacer un comando 'Mostrarme este archivo en el Explorador de Windows' - esto es lo que estoy tratando de lograr, y lo he hecho para archivos individuales.

Tenemos un ListView que permite a los usuarios seleccionar varios archivos dentro de la aplicación y moverlos/eliminarlos/etc. Sería bueno tener este comando 'mostrarme este archivo en Windows' para múltiples archivos seleccionados, al menos si todos los archivos fuente están en el mismo directorio, pero si no es posible, entonces no es una característica importante.

+0

Reemplazar 'mostrar este archivo en windows' por 'mostrar en la carpeta de windows' ('windows' es opcional aquí) - problema resuelto. – jfs

+0

@ J.F.Sebastian lo siento ... podría exponer un poco sobre esto. No entiendo cómo esto resuelve el problema de Orion Rewards ... tia. –

+0

@FlakDiNenno: Quise decir que (como una opción inferior) podría simplemente abrir la carpeta principal que contiene los archivos (sin seleccionar los archivos). [la respuesta de Flashk] (http://stackoverflow.com/a/3011284/4279) muestra cómo abrir la carpeta * y seleccionar los archivos *. – jfs

0

Supongo que puede usar FindWindowEx para obtener el SysListView32 del Explorador de Windows, luego use SendMessage con LVM_SETITEMSTATE para seleccionar los elementos. La dificultad es conocer la posición de los artículos ... Tal vez LVM_FINDITEM se puede utilizar para esto.

0

Grr me gustaría hacer esto también. Media Player lo hace cuando seleccionas 2+ archivos y haces clic con el botón derecho y haces "abrir ubicación de archivo" pero no estoy seguro de cómo (ni tampoco me apetece pasar el tiempo con el procmon para resolverlo).

5

La verdadera forma de seleccionar múltiples archivos en el Explorador es la siguiente

código no administrado se parece a esto (compilado de China mensajes de código con la fijación de sus errores)

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

Esto es realmente genial, trabajé mucho, gracias – joshcomley

Cuestiones relacionadas