2008-08-13 13 views
17

je peux afficher et sélectionner un seul fichier dans l'explorateur Windows comme ceci:Programmatically sélectionner plusieurs fichiers dans l'Explorateur Windows

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

Cependant, je ne peux pas travailler comment sélectionner plus d'un fichier. Aucune des permutations de select j'ai essayé de travailler.

Note: J'ai regardé ces pages pour les docs, ni aidé.

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

Répondre

16

Cela devrait être possible avec la fonction shell SHOpenFolderAndSelectItems

EDIT

Voici quelques exemples de code montrant comment utiliser la fonction en C/C++, sans vérification d'erreur:

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

Plus d'informations sur l'utilisation de cette méthode serait utile ... il ne semble y avoir rien sur pinvoke.net, et je ne suis pas super avec interop. – devios1

+0

J'ai mis à jour mon post pour contenir un exemple de code C/C++ – flashk

+0

Nice! Merci pour cela –

2

il ne peut se faire par explorer.exe

1

Selon ce que vous voulez vraiment vous accomplir peut-être en mesure de le faire avec AutoHotKey. C'est un outil gratuit incroyable pour automatiser les choses que vous ne pouvez normalement pas faire. Cela devrait venir avec Windows. Ce script sélectionne votre fichier et met en surbrillance les deux fichiers suivants en dessous lorsque vous cliquez sur F12.

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

Il est également possible de simplement mettre ces deux lignes du milieu dans un fichier texte, puis le transmettre est un parm à autohotkey.exe. Ils ont également une option pour compiler le script, ce qui en ferait un exe autonome que vous pourriez appeler. Fonctionne très bien avec un excellent fichier d'aide.

@Orion, Il est possible d'utiliser autohotkey à partir de C#. Vous pouvez faire un script autohotkey dans un exécutable autonome (environ 400k) qui peut être lancé par votre application C# (juste comme vous lancez l'explorateur). Vous pouvez également passer les paramètres de la ligne de commande. Il n'a aucune exigence d'exécution.

+0

Ne fonctionnera pas bien si les fichiers ne se sont pas après l'autre cependant? – Svish

+0

C'est pourquoi j'ai dit "en fonction" et "peut être capable de". Il y a beaucoup d'options dans autohotkey, y compris l'automatisation d'une recherche, je viens de donner un exemple. – bruceatk

+1

Je ne sais pas pourquoi c'est marqué. AutoHotkey est une excellente solution lorsque vous devez faire quelque chose que vous ne pouvez pas faire en utilisant une API existante. Il a beaucoup de garanties qui peuvent être utilisées pour s'assurer que le bon programme est ciblé. Il y a beaucoup de possibilités. La réponse qui est marquée comme une réponse n'est pas une réponse. C'est juste une déclaration évidente qui est la raison pour laquelle la question a été posée en premier lieu. Je suggère que quiconque annoter cette réponse devrait d'abord se pencher sur AutoHotkey et apprendre ce qu'il peut faire. Il devrait être construit dans les fenêtres. – bruceatk

1

C'est une de ces questions où il peut être bon de considérer ce que vous essayez d'atteindre, et s'il existe une meilleure méthode.

Pour ajouter un peu plus de contexte - Notre société développe une application client C#, qui permet aux utilisateurs de charger des fichiers et faire des choses avec eux, un peu comme la façon dont iTunes gère vos fichiers MP3 sans vous montrer le fichier réel sur le disque .

Il est utile de sélectionner un fichier dans l'application et de lancer la commande «Montrez-moi ce fichier dans l'Explorateur Windows» - c'est ce que j'essaie d'obtenir, et ce pour des fichiers uniques.

Nous avons un ListView qui permet aux utilisateurs de sélectionner plusieurs fichiers dans l'application, et de les déplacer/supprimer/etc. Ce serait bien d'avoir ce travail de commande 'montrez-moi ce fichier dans Windows' pour plusieurs fichiers sélectionnés - au moins si tous les fichiers source sont dans le même répertoire, mais si ce n'est pas possible, ce n'est pas une fonctionnalité majeure.

+0

Remplacer «me montrer ce fichier dans les fenêtres» par «montrer dans le dossier Windows» («windows» est facultatif ici) - problème résolu. – jfs

+0

@ J.F.Sebastian désolé ... pourriez-vous expliquer un peu. Je ne comprends pas comment cela résout le problème d'OrionEdwards ... tia. –

+0

@FlakDiNenno: Je voulais dire que (en tant qu'option inférieure), vous pouvez simplement ouvrir le dossier parent qui contient les fichiers (sans sélectionner les fichiers). [La réponse de flashk] (http://stackoverflow.com/a/3011284/4279) montre comment ouvrir le dossier * et sélectionner les fichiers *. – jfs

0

Je suppose que vous pouvez utiliser FindWindowEx pour obtenir le SysListView32 de Windows Explorer, puis utiliser SendMessage avec LVM_SETITEMSTATE pour sélectionner les éléments. La difficulté étant de connaître la position des objets ... Peut-être que LVM_FINDITEM peut être utilisé pour cela.

0

Je voudrais faire cela aussi. Media Player le fait quand vous sélectionnez 2+ fichiers et faites un clic droit et faites "ouvrir l'emplacement du fichier" mais pas exactement sûr de comment (et je n'ai pas vraiment envie de passer le temps w/procmon pour le comprendre).

5

La véritable façon de sélectionner plusieurs fichiers dans l'explorateur est la suivante

Le code non géré ressemble à ceci (compilé à partir des messages de code de la Chine avec fixer ses bogues)

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

C'est vraiment génial, a travaillé un régal merci – joshcomley