2008-08-13 15 views
17

ich eine einzelne Datei im Windows Explorer wie diese anzeigen und auswählen:wählen Programmatically mehrere Dateien in Windows Explorer

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

Allerdings kann ich nicht arbeiten, wie mehr als eine Datei auszuwählen. Keine der Permutationen von Select habe ich ausprobiert.

Hinweis: Ich habe diese Seiten für Dokumente angesehen, keine geholfen.

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

Antwort

16

Dies sollte mit der Shell-Funktion SHOpenFolderAndSelectItems

EDIT

Hier ist ein Beispielcode zeigt, wie Sie mit der Funktion in C/C++, ohne Fehlerprüfung möglich sein:

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

Weitere Informationen zur Verwendung dieser Methode wäre hilfreich ... es scheint nichts auf pinvoke.net drauf zu sein, und ich bin nicht großartig mit Interop. – devios1

+0

Ich habe meinen Beitrag aktualisiert, um Beispielcode C/C++ zu enthalten – flashk

+0

Schön! Danke für das –

2

es nicht durch

explorer.exe getan werden kann
1

Je nachdem, was Sie wirklich wollen, es mit AutoHotKey erreichen können Sie in der Lage zu tun. Es ist ein erstaunliches kostenloses Werkzeug für die Automatisierung von Dingen, die Sie normalerweise nicht tun können. Es sollte mit Windows kommen. Dieses Skript wählt Ihre Datei aus und markiert die nächsten zwei Dateien darunter, wenn Sie F12 drücken.

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

Es ist auch möglich, nur die beiden mittleren Zeilen in einer Textdatei zu setzen und dann geben sie ein Parm ist zu AutoHotkey.exe. Sie haben eine Option, das Skript auch zu kompilieren, was es zu einer eigenständigen exe machen würde, die Sie aufrufen könnten. Funktioniert hervorragend mit einer großen Hilfedatei.

@Orion, es ist möglich, autohotkey von C# zu verwenden. Sie können ein autohotkey-Skript in eine eigenständige ausführbare Datei (ca. 400 KB) umwandeln, die von Ihrer C# -App gestartet werden kann (genau wie Sie den Explorer starten). Sie können auch Befehlszeilenparameter übergeben. Es hat keine Laufzeitanforderungen.

+0

Funktioniert es nicht gut, wenn die Dateien nicht aufeinander folgen? – Svish

+0

Deshalb habe ich gesagt "abhängig" und "kann". Es gibt viele Optionen innerhalb von autohotkey einschließlich der Automatisierung einer Suche, ich gab nur ein Beispiel. – bruceatk

+1

Ich bin nicht sicher, warum dies markiert ist. AutoHotkey ist eine ausgezeichnete Lösung, wenn Sie etwas tun müssen, was Sie mit einer vorhandenen API nicht tun können. Es hat viele Sicherheitsmaßnahmen, die verwendet werden können, um sicherzustellen, dass das richtige Programm gezielt ist. Es gibt viele Möglichkeiten. Die Antwort, die als Antwort markiert ist, ist keine Antwort. Es ist nur eine offensichtliche Aussage, weshalb die Frage überhaupt gestellt wurde. Ich würde vorschlagen, dass jeder, der diese Antwort markiert, sich zuerst mit AutoHotkey beschäftigen und lernen sollte, was er tun kann. Es sollte in Windows eingebaut werden. – bruceatk

1

Dies ist eine dieser Fragen, bei denen es gut ist zu überlegen, was Sie erreichen möchten und ob es eine bessere Methode gibt.

etwas mehr Kontext hinzufügen - Unsere Firma hat eine Anwendung C# Client entwickelt, mit denen Benutzer Dateien laden können und mit ihnen Dinge zu tun, ein bisschen wie, wie iTunes Ihre MP3-Dateien verwaltet, ohne dass Sie die eigentliche Datei auf der Festplatte zeigt, .

Es ist nützlich, eine Datei in der Anwendung auszuwählen und einen Befehl "Diese Datei in Windows Explorer anzeigen" auszuführen - das ist es, was ich versuche zu erreichen, und zwar für einzelne Dateien.

Wir haben eine ListView, mit der Benutzer mehrere Dateien innerhalb der Anwendung auswählen können, und verschieben/löschen/etc sie. Es wäre schön, wenn der Befehl "Diese Datei in Windows anzeigen" für mehrere ausgewählte Dateien funktioniert - zumindest wenn sich alle Quelldateien im selben Verzeichnis befinden, aber wenn dies nicht möglich ist, dann ist das kein großes Feature.

+0

Ersetze 'Zeige mir diese Datei in Windows' durch 'Zeige im Windows Ordner' ('Windows' ist hier optional) - Problem gelöst. – jfs

+0

@ J.F.Sebastian Entschuldigung ... könntest du ein wenig darüber sprechen. Ich verstehe nicht, wie das Problem von OrionEdwards gelöst wird ... tia. –

+0

@FlakDiNenno: Ich meinte, dass (als eine minderwertige Option) Sie einfach den übergeordneten Ordner öffnen können, der die Dateien enthält (ohne die Dateien auszuwählen). [flask's answer] (http://stackoverflow.com/a/3011284/4279) zeigt, wie man den Ordner * öffnet und die Dateien auswählt *. – jfs

0

Ich nehme an, Sie FindWindowEx verwenden können die SysListView32 von Windows Explorer zu erhalten, dann verwenden SendMessage mit LVM_SETITEMSTATE die Elemente auszuwählen. Die Schwierigkeit besteht darin, die Position der Artikel zu kennen ... Vielleicht kann dafür LVM_FINDITEM verwendet werden.

0

Grr möchte ich das auch tun. Media Player tut es, wenn Sie 2+ Dateien auswählen und mit der rechten Maustaste klicken und "Dateispeicherort öffnen", aber nicht genau sicher, wie (und ich habe auch keine Lust, die Zeit mit procmon zu verbringen, um es herauszufinden).

5

Die richtige Art der Auswahl mehrerer Dateien im Explorer ist die nächste

Unmanaged Code sieht so aus (kompiliert aus China-Code-Posts mit der Behebung seiner Fehler)

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

Das ist wirklich toll, funktionierte ein Leckerbissen dank – joshcomley

Verwandte Themen