Vælg programmelt flere filer i Windows Explorer

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg kan vise og vælge en enkelt fil i Windows Explorer som denne:


explorer.exe /select, "c:path	ofile.txt"


Jeg kan dog ikke udarbejde, hvordan man vælger mere end en fil. Ingen af ​​de permutationer, jeg har valgt, har jeg forsøgt at arbejde på.


Bemærk: Jeg kiggede på disse sider til docs, heller ikke hjulpet.


https://support.microsoft.com/kb/314853

http://www.infocellar.com/Win98/explorer-switches.htm[10][11]

Bedste reference


Dette skal være muligt med skalfunktionen SHOpenFolderAndSelectItems [12]


EDIT


Her er nogle eksempler, der viser, hvordan man bruger funktionen i C/C ++ uden fejlcheckning:


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

Andre referencer 1


Den rigtige måde at vælge flere filer på i Explorer er den næste


Uhåndteret kode ser sådan ud (kompileret fra Kina-kodeindlæg med fastsættelse af sine fejl)


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

Andre referencer 2


det kan ikke gøres gennem explorer.exe

Andre referencer 3


Afhængigt af hvad du rent faktisk vil opnå, kan du muligvis gøre det med AutoHotKey. Det er et fantastisk gratis værktøj til at automatisere ting, som du normalt ikke kan gøre. Det skal komme med Windows. Dette script vælger din fil og fremhæver de to næste filer under det, når du rammer F12. [13]


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


Det er også muligt at bare sætte disse to mellemlinjer i en tekstfil og derefter passere det er en parm til autohotkey.exe. De har også mulighed for at kompilere scriptet, hvilket ville gøre det til en selvstændig exe, som du kunne ringe til. Fungerer godt med en stor hjælpefil.


@Orion, Det er muligt at bruge autohotkey fra C #. Du kan lave et autohotkey-script til en selvstændig eksekverbar (ca. 400k), der kan lanceres af din C # app (ligesom du lancerer explorer). Du kan også sende det kommandolinjeparametre. Det har ikke nogen runtime krav.

Andre referencer 4



  Dette er et af de spørgsmål, hvor det kan være godt at overveje, hvad du forsøger at opnå, og om der er en bedre metode.



For at tilføje mere kontekst -
Vores firma udvikler en C # klientprogram, som giver brugerne mulighed for at indlæse filer og gøre ting med dem, ligesom om, hvordan iTunes styrer dine MP3-filer uden at vise dig den egentlige fil på disken.


Det er nyttigt at vælge en fil i applikationen, og gøre en 'Vis mig denne fil i Windows Explorer' kommando - det er det jeg forsøger at opnå, og har gjort det for enkelt filer.


Vi har en ListView, der giver brugerne mulighed for at vælge flere filer inden for applikationen, og flytte/slette/etc dem. Det ville være rart at have denne 'Vis mig denne fil i Windows' kommando arbejde for flere valgte filer - i hvert fald hvis alle kildefiler er i samme mappe, men hvis det ikke er muligt så er det ikke en vigtig funktion .

Andre referencer 5


Jeg antager, at du kan bruge FindWindowEx for at få SysListView32 til Windows Explorer, og brug derefter SendMessage med LVM\_SETITEMSTATE for at vælge emnerne. Vanskeligheden ved at kende positionen af ​​emnerne ... Måske kan LVM\_FINDITEM bruges til dette.

Andre referencer 6


Grr det vil jeg også gerne gøre. Media Player gør det, når du vælger 2 + filer og højreklikker og gør 'open file location' men ikke helt sikker på hvordan (heller ikke jeg virkelig føler mig som at bruge tiden med at få det til at finde ud af det).