Pregunta

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 manera de seleccionar más de un archivo.Ninguna de las permutaciones de select que he probado funciona.

Nota:Miré estas páginas en busca de documentos y ninguno de los dos ayudó.

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

¿Fue útil?

Solución

Esto debería ser posible con la función 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);

Otros consejos

La verdadera forma de seleccionar varios archivos en Explorer es la siguiente

El código no administrado se ve así (compilado a partir de publicaciones de código de China para corregir 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 quieras lograr, es posible que puedas 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 dos archivos siguientes 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 simplemente poner esas dos líneas centrales en un archivo de texto y luego pasarlo como parámetro a autohotkey.exe.También tienen una opción para compilar el script, lo que lo convertiría en un archivo ejecutable independiente al que podrías llamar.Funciona muy bien con un gran archivo de ayuda.

@Orion, es posible utilizar autohotkey desde C#.Puede convertir un script de autohotkey en un ejecutable independiente (aproximadamente 400k) que puede iniciar su aplicación C# (tal como está iniciando el explorador).También puede pasarle 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ás tratando de lograr y si existe un método mejor.

Para agregar un poco más de contexto: nuestra empresa desarrolla una aplicación de cliente C#, que permite a los usuarios cargar archivos y hacer cosas con ellos, algo así como iTunes administra sus archivos MP3 sin mostrarle el archivo real en el disco.

Es útil seleccionar un archivo en la aplicación y ejecutar el comando "Muéstrame 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 que este comando 'muéstrame este archivo en Windows' funcione para varios 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 puedes usar FindWindowEx para obtener SysListView32 del Explorador de Windows, luego use SendMessage con LVM_SETITEMSTATE para seleccionar los elementos.La dificultad es saber la posición de los artículos...Tal vez LVM_FINDITEM se puede utilizar para esto.

Grr, a mí también me gustaría hacer esto.Media Player lo hace cuando seleccionas más de 2 archivos y haces clic derecho y "abrir ubicación del archivo", pero no estoy exactamente seguro de cómo (ni tengo ganas de pasar el tiempo con procmon para resolverlo).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top