2008-08-13 8 views
17

mogę wyświetlić i wybrać pojedynczy plik w Eksploratorze Windows tak:Programowo wybrać wiele plików w Eksploratorze Windows

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

Jednak nie mogę pracować się, jak wybrać więcej niż jeden plik. Żadna z permutacji selekcji, której próbowałem, nie działa.

Uwaga: Przeglądałem te strony w poszukiwaniu dokumentów, nie pomogłem.

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

Odpowiedz

16

To powinno być możliwe z funkcją powłoki SHOpenFolderAndSelectItems

EDIT

Oto przykładowy kod pokazujący jak korzystać z funkcji w C/C++, bez sprawdzania błędów:

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

Dowolne informacje na temat korzystania z tej metody byłyby pomocne ... nie ma w niej nic na ten temat, a nie jestem świetny we współpracy. – devios1

+0

Zaktualizowałem swój post, aby zawierał przykładowy kod C/C++. – flashk

+0

Nice! Dzięki za to –

2

nie może być wykonane przez explorer.exe

1

W zależności od tego, co faktycznie chcemy osiągnąć może być w stanie zrobić to z AutoHotKey. To niesamowite darmowe narzędzie do automatyzacji rzeczy, których normalnie nie możesz zrobić. Powinien pochodzić z Windows. Ten skrypt wybierze twój plik i podświetli następne dwa pliki poniżej po naciśnięciu F12.

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

Możliwe jest również, aby po prostu umieścić te dwa środkowe linie w pliku tekstowym, a następnie przekazać to parmezanem do autohotkey.exe. Mają także opcję kompilacji skryptu, co czyni go samodzielnym serwerem exe, który można wywołać. Działa wspaniale dzięki świetnemu plikowi pomocy.

@Orion, Możliwe jest użycie autohotkey z C#. Możesz zrobić skrypt autohotkey w samodzielnym pliku wykonywalnym (około 400k), który może zostać uruchomiony przez twoją aplikację C# (po prostu tak, jak uruchamiasz eksplorator). Możesz także przekazać parametry wiersza poleceń. Nie ma żadnych wymagań dla środowiska wykonawczego.

+0

Nie działa dobrze, jeśli pliki nie występują po sobie? – Svish

+0

Dlatego powiedziałem "zależny" i "może być w stanie". Istnieje wiele opcji w obrębie autohotkey, w tym automatyzacja wyszukiwania, podałem tylko jeden przykład. – bruceatk

+1

Nie jestem pewien, dlaczego jest to zaznaczone. AutoHotkey to doskonałe rozwiązanie, gdy trzeba zrobić coś, czego nie można zrobić przy użyciu istniejącego API. Ma wiele zabezpieczeń, które można wykorzystać w celu zapewnienia, że ​​właściwy program jest ukierunkowany. Istnieje wiele możliwości. Odpowiedź oznaczona jako odpowiedź nie jest odpowiedzią. To tylko oczywiste stwierdzenie, z powodu którego pytanie zostało zadane w pierwszej kolejności. Sugerowałbym, aby ktokolwiek, kto wyznaczył tę odpowiedź, powinien najpierw zajrzeć do AutoHotkey i dowiedzieć się, co potrafi. Powinien być wbudowany w okna. – bruceatk

1

Jest to jedno z tych pytań, w których dobrze jest rozważyć, co próbujesz osiągnąć i czy istnieje lepsza metoda.

Aby dodać trochę więcej kontekstu - Nasza firma rozwija aplikację kliencką C#, który umożliwia użytkownikom załadować pliki i robić rzeczy z nimi, tak jakby jak iTunes zarządza plików MP3 bez pokazując plik rzeczywiste na dysku .

Przydatne jest wybranie pliku w aplikacji i wykonanie polecenia "Pokaż ten plik w Eksploratorze Windows" - to jest to, co staram się osiągnąć, i zrobiłem to dla pojedynczych plików.

Mamy ListView, który pozwala użytkownikom wybrać wiele plików w aplikacji i przenieść/usunąć/etc ich. Byłoby miło mieć to polecenie "pokaż mi ten plik w Windows" dla wielu wybranych plików - przynajmniej jeśli wszystkie pliki źródłowe są w tym samym katalogu, ale jeśli nie jest to możliwe, to nie jest to ważna funkcja.

+0

Zamień "pokaż mi ten plik w systemie Windows" przez "pokaż w folderze Windows" ("Windows" jest opcjonalny tutaj) - problem został rozwiązany. – jfs

+0

@ J.F.Sebastian przepraszam ... mógłbyś to wyjaśnić. Nie rozumiem, jak rozwiązuje to problem OrionEdwards ... tia. –

+0

@FlakDiNenno: Miałem na myśli, że (jako gorszej opcji) można po prostu otworzyć folder nadrzędny, który zawiera pliki (bez wybierania plików). [odpowiedź flashka] (http://stackoverflow.com/a/3011284/4279) pokazuje, jak otworzyć folder * i wybrać pliki *. – jfs

0

Przypuszczam, że można użyć FindWindowEx, aby pobrać SysListView32 z Eksploratora Windows, a następnie użyć SendMessage z LVM_SETITEMSTATE, aby wybrać elementy. Trudność polega na poznaniu pozycji przedmiotów ... Być może można do tego użyć LVM_FINDITEM.

0

Grr Chciałbym to zrobić również. Media Player robi to po wybraniu 2 + plików i kliknięciu prawym przyciskiem myszy i "otwórz lokalizację pliku", ale nie do końca pewny jak (ani nie mam ochoty spędzać czasu w/procmon, aby to rozgryźć).

5

Prawdziwy sposób wybierania wielu plików w Eksploratorze to następny

Niezarządzany kod wygląda tak (skompilowany z chińskich postów kodu z naprawianiem błędów)

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

To jest naprawdę świetne, zadziałało dzięki – joshcomley

Powiązane problemy