Question

Je peux afficher et sélectionner un seul fichier dans l'explorateur Windows comme ceci :

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

Cependant, je n'arrive pas à comprendre comment sélectionner plusieurs fichiers.Aucune des permutations de sélection que j'ai essayées ne fonctionne.

Note:J'ai regardé ces pages pour la documentation, ni l'une ni l'autre n'a aidé.

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

Était-ce utile?

La solution

Cela devrait être possible avec la fonction shell SHOpenFolderAndSelectItems

MODIFIER

Voici un exemple 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);

Autres conseils

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 publications de code chinoises avec correction de ses bugs)

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

cela ne peut pas être fait via explorer.exe

En fonction de ce que vous voulez réellement accomplir, vous pourrez peut-être le faire avec Touche de raccourci automatique.C'est un outil gratuit incroyable pour automatiser des choses que vous ne pouvez normalement pas faire.Il devrait venir avec Windows.Ce script sélectionnera votre fichier et mettra en surbrillance les deux fichiers suivants en dessous lorsque vous appuyez 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 de transmettre ce paramètre à autohotkey.exe.Ils ont également la possibilité de 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 l'autohotkey depuis C#.Vous pouvez transformer un script autohotkey en un exécutable autonome (environ 400 000 k) qui peut être lancé par votre application C# (de la même manière que vous lancez l'explorateur).Vous pouvez également lui transmettre des paramètres de ligne de commande.Il n’a aucune exigence d’exécution.

C'est l'une de ces questions pour lesquelles il peut être bon de réfléchir à ce que vous essayez d'accomplir et de savoir s'il existe une meilleure méthode.

Pour ajouter un contexte supplémentaire - notre entreprise développe une application client C #, qui permet aux utilisateurs de charger des fichiers et de 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 d'exécuter une commande « Montre-moi ce fichier dans l'Explorateur Windows » - c'est ce que j'essaie de réaliser, et je l'ai fait 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 que cette commande « montrez-moi ce fichier dans Windows » fonctionne pour plusieurs fichiers sélectionnés - du moins si tous les fichiers sources se trouvent dans le même répertoire, mais si ce n'est pas possible, ce n'est pas une fonctionnalité majeure.

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

Grr, j'aimerais faire ça aussi.Media Player le fait lorsque vous sélectionnez plus de 2 fichiers et faites un clic droit et faites "ouvrir l'emplacement du fichier", mais je ne sais pas exactement comment (et je n'ai pas vraiment envie de passer du temps avec procmon pour le comprendre).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top