Progtwig programáticamente selecciona múltiples archivos en el explorador de Windows

Puedo mostrar y seleccionar un solo archivo en el explorador de Windows de esta manera:

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

Sin embargo, no puedo encontrar la forma 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

Esto debería ser posible con la función de shell SHOpenFolderAndSelectItems

EDITAR

Aquí hay un código de muestra que muestra cómo usar la función en C / C ++, sin verificació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); 

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

El código no administrado se ve así (comstackdo de las publicaciones del código de China con la reparació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); } } } 

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

Dependiendo de lo que realmente desee lograr, puede 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 colocar esas dos líneas intermedias en un archivo de texto y luego pasarlo es parm a autohotkey.exe. También tienen la opción de comstackr 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 usar autohotkey desde 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.

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 agregar un poco más de contexto: nuestra compañía desarrolla una aplicación de cliente C #, que permite a los usuarios cargar archivos y hacer cosas con ellos, algo así como cómo iTunes maneja sus archivos MP3 sin mostrarle el archivo real en el disco.

Es útil seleccionar un archivo en la aplicación y hacer un comando “Mostrarme este archivo en el Explorador de Windows”: esto es lo que bash lograr, y lo he hecho para los archivos individuales.

Tenemos un ListView que permite a los usuarios seleccionar múltiples 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.

Supongo que puede usar FindWindowEx para obtener SysListView32 del Explorador de Windows y luego usar SendMessage con LVM_SETITEMSTATE para seleccionar los elementos. La dificultad es conocer la posición de los artículos … Quizás LVM_FINDITEM se puede usar para esto.

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).