Domanda

Posso visualizzare e selezionare un singolo file in Windows Explorer in questo modo:

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

Tuttavia, non riesco a capire come selezionare più di un file.Nessuna delle permutazioni di selezione che ho provato funziona.

Nota:Ho cercato documenti in queste pagine, nessuno dei due ha aiutato.

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

È stato utile?

Soluzione

Questo dovrebbe essere possibile con la funzione shell SHOpenFolderAndSelectItems

MODIFICARE

Ecco del codice di esempio che mostra come utilizzare la funzione in C/C++, senza controllo degli errori:

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

Altri suggerimenti

Il vero modo di selezionare più file in Explorer è il successivo

Il codice non gestito si presenta così (compilato dai post di codice cinese con la correzione dei relativi bug)

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

non può essere fatto tramite explorer.exe

A seconda di ciò che vuoi effettivamente realizzare, potresti essere in grado di farlo AutoHotKey.È uno straordinario strumento gratuito per automatizzare cose che normalmente non puoi fare.Dovrebbe essere fornito con Windows.Questo script selezionerà il tuo file ed evidenzierà i due file successivi sotto di esso quando premi F12.

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

È anche possibile semplicemente inserire queste due righe centrali in un file di testo e poi passarle come parm ad autohotkey.exe.Hanno anche un'opzione per compilare lo script, il che lo renderebbe un exe autonomo che potresti chiamare.Funziona alla grande con un ottimo file di aiuto.

@Orion, è possibile utilizzare l'autohotkey da C#.Puoi creare uno script autohotkey in un eseguibile autonomo (circa 400k) che può essere avviato dalla tua app C# (proprio come stai avviando Explorer).Puoi anche passargli i parametri della riga di comando.Non ha requisiti di runtime.

Questa è una di quelle domande per cui potrebbe essere utile considerare ciò che stai cercando di ottenere e se esiste un metodo migliore.

Per aggiungere un po 'più di contesto: la nostra azienda sviluppa un'applicazione client C#, che consente agli utenti di caricare file e fare cose con loro, un po' come il modo in cui iTunes gestisce i tuoi file MP3 senza mostrarti il ​​file effettivo sul disco.

È utile selezionare un file nell'applicazione ed eseguire il comando "Mostrami questo file in Esplora risorse": questo è ciò che sto cercando di ottenere e l'ho fatto per singoli file.

Abbiamo un ListView che consente agli utenti di selezionare più file all'interno dell'applicazione e spostarli/eliminarli/ecc.Sarebbe bello che questo comando "mostrami questo file in Windows" funzioni per più file selezionati, almeno se tutti i file sorgente si trovano nella stessa directory, ma se non è possibile, non è una funzionalità importante.

Suppongo che tu possa usare FindWindowEx per ottenere SysListView32 di Windows Explorer, quindi utilizzare SendMessage con LVM_SETITEMSTATE per selezionare gli elementi.La difficoltà sta nel conoscere la posizione degli oggetti...Forse LVM_FINDITEM può essere utilizzato per questo.

Grr, vorrei farlo anch'io.Media Player lo fa quando selezioni più di 2 file, fai clic con il pulsante destro del mouse e fai "apri posizione file", ma non sono esattamente sicuro di come (né ho davvero voglia di passare il tempo con Procmon per capirlo).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top