C #: Comment ouvrir les fenêtres de Windows Explorer avec un certain nombre de fichiers sélectionnés

StackOverflow https://stackoverflow.com/questions/1073353

Question

Dans la bibliothèque de Windows Media Player, vous pouvez sélectionner un ou plusieurs fichiers musicaux. Vous pouvez ensuite le clic droit et dans leur menu contextuel, choisissez Ouvrir l'emplacement du fichier . Cela ouvrira une fenêtre fenêtre de l'explorateur pour chaque répertoire que les fichiers sont, et les fichiers seront sélectionnés pour vous.

Alors disons que nous avons un tas de fichiers mp3 dans notre bibliothèque où trois d'entre eux sont les suivants:

  • Z: \ Musique \ jeudi Blues \ 01. Je souhaite qu'il était friday.mp3
  • Z: \ Musique \ Counting Sheep \ 01. Sheep # 1.mp3
  • Z: \ Musique \ Counting Sheep \ 02. Sheep # 2.mp3

Si nous choisissons ces trois (dans une vue où tous sont visibles) et faire Ouvrir l'emplacement du fichier puis deux fenêtres de l'explorateur surgiront. On le Z: \ Musique \ jeudi Blues dossier avec 01. Je souhaite qu'il était friday.mp3 sélectionné, et l'autre sera le * Z: \ Musique \ Counting Sheep dossier ** avec les deux 01. Sheep # 1.mp3 et 02. Sheep # 2.mp3 sélectionné.

Comment puis-je faire moi-même en C #? Nous avons une application qui va exporter des données vers différents formats, par exemple CSV et Excel, et je voudrais ouvrir les fenêtres de l'explorateur avec ces fichiers sélectionnés quand ils sont créés et prêts à être vu. Actuellement, je fais juste Process.Start(path), et cela fonctionne, mais j'aimerais être en mesure de mettre en évidence les fichiers particuliers ainsi. Ferait les fichiers qui ont été créés juste beaucoup plus évident.


Windows Media Player, il fait si bien ... Je veux le faire aussi = / Y a-t-il des employés de Microsoft ici qui pourrait comprendre comment il peut être fait? (A)

Était-ce utile?

La solution

La recherche d'une réponse après un collègue de travail avait la question que j'ai trouvé aucun donc j'écrit une petite classe pour le faire. Le code est Gist et je vais coller la version curent à la fin de ce post.

Avec vos fichiers d'exemple, la syntaxe sera:

ShowSelectedInExplorer.FilesOrFolders(
    @"Z:\Music\Thursday Blues\01. I wish it was friday.mp3",
    @"Z:\Music\Counting Sheep\01. Sheep #1.mp3",
    @"Z:\Music\Counting Sheep\02. Sheep #2.mp3"
    );

Il y a des limites à mon code par rapport à l'API de bas niveau, principalement:

  • Sélection sur le bureau n'est pas implémentée
  • Le répertoire parent doit être un répertoire ou un lecteur, de sorte que vous ne pouvez pas sélectionner plusieurs lecteurs dans le dossier Poste de travail, par exemple.

Quoi qu'il en soit, voici le code source de la classe ShowSelectedInExplorer:

namespace SHOpenFolderAndSelectItems
{
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Runtime.CompilerServices;
    using System.Runtime.InteropServices;
    using System.Runtime.InteropServices.ComTypes;

    static class ShowSelectedInExplorer
    {
        [Flags]
        enum SHCONT : ushort
        {
            SHCONTF_CHECKING_FOR_CHILDREN = 0x0010,
            SHCONTF_FOLDERS = 0x0020,
            SHCONTF_NONFOLDERS = 0x0040,
            SHCONTF_INCLUDEHIDDEN = 0x0080,
            SHCONTF_INIT_ON_FIRST_NEXT = 0x0100,
            SHCONTF_NETPRINTERSRCH = 0x0200,
            SHCONTF_SHAREABLE = 0x0400,
            SHCONTF_STORAGE = 0x0800,
            SHCONTF_NAVIGATION_ENUM = 0x1000,
            SHCONTF_FASTITEMS = 0x2000,
            SHCONTF_FLATLIST = 0x4000,
            SHCONTF_ENABLE_ASYNC = 0x8000
        }

        [ComImport,
        Guid("000214E6-0000-0000-C000-000000000046"),
        InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
        ComConversionLoss]
        interface IShellFolder
        {
            [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
            void ParseDisplayName(IntPtr hwnd, [In, MarshalAs(UnmanagedType.Interface)] IBindCtx pbc, [In, MarshalAs(UnmanagedType.LPWStr)] string pszDisplayName, [Out] out uint pchEaten, [Out] out IntPtr ppidl, [In, Out] ref uint pdwAttributes);
            [PreserveSig]
            [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
            int EnumObjects([In] IntPtr hwnd, [In] SHCONT grfFlags, [MarshalAs(UnmanagedType.Interface)] out IEnumIDList ppenumIDList);

            [PreserveSig]
            [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
            int BindToObject([In] IntPtr pidl, [In, MarshalAs(UnmanagedType.Interface)] IBindCtx pbc, [In] ref Guid riid, [Out, MarshalAs(UnmanagedType.Interface)] out IShellFolder ppv);

            [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
            void BindToStorage([In] ref IntPtr pidl, [In, MarshalAs(UnmanagedType.Interface)] IBindCtx pbc, [In] ref Guid riid, out IntPtr ppv);

            [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
            void CompareIDs([In] IntPtr lParam, [In] ref IntPtr pidl1, [In] ref IntPtr pidl2);

            [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
            void CreateViewObject([In] IntPtr hwndOwner, [In] ref Guid riid, out IntPtr ppv);

            [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
            void GetAttributesOf([In] uint cidl, [In] IntPtr apidl, [In, Out] ref uint rgfInOut);


            [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
            void GetUIObjectOf([In] IntPtr hwndOwner, [In] uint cidl, [In] IntPtr apidl, [In] ref Guid riid, [In, Out] ref uint rgfReserved, out IntPtr ppv);

            [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
            void GetDisplayNameOf([In] ref IntPtr pidl, [In] uint uFlags, out IntPtr pName);

            [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
            void SetNameOf([In] IntPtr hwnd, [In] ref IntPtr pidl, [In, MarshalAs(UnmanagedType.LPWStr)] string pszName, [In] uint uFlags, [Out] IntPtr ppidlOut);
        }

        [ComImport,
        Guid("000214F2-0000-0000-C000-000000000046"),
        InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        interface IEnumIDList
        {
            [PreserveSig]
            [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
            int Next(uint celt, IntPtr rgelt, out uint pceltFetched);

            [PreserveSig]
            [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
            int Skip([In] uint celt);

            [PreserveSig]
            [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
            int Reset();

            [PreserveSig]
            [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
            int Clone([MarshalAs(UnmanagedType.Interface)] out IEnumIDList ppenum);
        }

        static class NativeMethods
        {
            [DllImport("shell32.dll", EntryPoint = "SHGetDesktopFolder", CharSet = CharSet.Unicode,
                SetLastError = true)]
            static extern int SHGetDesktopFolder_([MarshalAs(UnmanagedType.Interface)] out IShellFolder ppshf);

            public static IShellFolder SHGetDesktopFolder()
            {
                IShellFolder result;
                Marshal.ThrowExceptionForHR(SHGetDesktopFolder_(out result));
                return result;
            }

            [DllImport("shell32.dll", EntryPoint = "SHOpenFolderAndSelectItems")]
            static extern int SHOpenFolderAndSelectItems_(
                [In] IntPtr pidlFolder, uint cidl, [In, Optional, MarshalAs(UnmanagedType.LPArray)] IntPtr[] apidl,
                int dwFlags);

            public static void SHOpenFolderAndSelectItems(IntPtr pidlFolder, IntPtr[] apidl, int dwFlags)
            {
                var cidl = (apidl != null) ? (uint)apidl.Length : 0U;
                var result = SHOpenFolderAndSelectItems_(pidlFolder, cidl, apidl, dwFlags);
                Marshal.ThrowExceptionForHR(result);
            }

            [DllImport("shell32.dll")]
            public static extern void ILFree([In] IntPtr pidl);
        }

        static IntPtr GetShellFolderChildrenRelativePIDL(IShellFolder parentFolder, string displayName)
        {
            uint pchEaten;
            uint pdwAttributes = 0;
            IntPtr ppidl;
            parentFolder.ParseDisplayName(IntPtr.Zero, null, displayName, out pchEaten, out ppidl, ref pdwAttributes);

            return ppidl;
        }

        static IntPtr PathToAbsolutePIDL(string path)
        {
            var desktopFolder = NativeMethods.SHGetDesktopFolder();
            return GetShellFolderChildrenRelativePIDL(desktopFolder, path);
        }

        static Guid IID_IShellFolder = typeof(IShellFolder).GUID;

        static IShellFolder PIDLToShellFolder(IShellFolder parent, IntPtr pidl)
        {
            IShellFolder folder;
            var result = parent.BindToObject(pidl, null, ref IID_IShellFolder, out folder);
            Marshal.ThrowExceptionForHR((int)result);
            return folder;
        }

        static IShellFolder PIDLToShellFolder(IntPtr pidl)
        {
            return PIDLToShellFolder(NativeMethods.SHGetDesktopFolder(), pidl);
        }

        static void SHOpenFolderAndSelectItems(IntPtr pidlFolder, IntPtr[] apidl, bool edit)
        {
            NativeMethods.SHOpenFolderAndSelectItems(pidlFolder, apidl, edit ? 1 : 0);
        }

        public static void FileOrFolder(string path, bool edit = false)
        {
            if (path == null) throw new ArgumentNullException("path");

            var pidl = PathToAbsolutePIDL(path);
            try
            {
                SHOpenFolderAndSelectItems(pidl, null, edit);
            }
            finally
            {
                NativeMethods.ILFree(pidl);
            }
        }

        static IEnumerable<FileSystemInfo> PathToFileSystemInfo(IEnumerable<string> paths)
        {
            foreach (var path in paths)
            {
                var fixedPath = path;
                if (fixedPath.EndsWith(Path.DirectorySeparatorChar.ToString())
                    || fixedPath.EndsWith(Path.AltDirectorySeparatorChar.ToString()))
                {
                    fixedPath = fixedPath.Remove(fixedPath.Length - 1);
                }

                if (Directory.Exists(fixedPath))
                {
                    yield return new DirectoryInfo(fixedPath);
                }
                else if (File.Exists(fixedPath))
                {
                    yield return new FileInfo(fixedPath);
                }
                else
                {
                    throw new FileNotFoundException
                        (string.Format("The specified file or folder doesn't exists : {0}", fixedPath),
                        fixedPath);
                }
            }
        }

        public static void FilesOrFolders(string parentDirectory, ICollection<string> filenames)
        {
            if (filenames == null) throw new ArgumentNullException("filenames");
            if (filenames.Count == 0) return;

            var parentPidl = PathToAbsolutePIDL(parentDirectory);
            try
            {
                var parent = PIDLToShellFolder(parentPidl);
                var filesPidl = filenames
                    .Select(filename => GetShellFolderChildrenRelativePIDL(parent, filename))
                    .ToArray();

                try
                {
                    SHOpenFolderAndSelectItems(parentPidl, filesPidl, false);
                }
                finally
                {
                    foreach (var pidl in filesPidl)
                    {
                        NativeMethods.ILFree(pidl);
                    }
                }
            }
            finally
            {
                NativeMethods.ILFree(parentPidl);
            }
        }

        public static void FilesOrFolders(params string[] paths)
        {
            FilesOrFolders((IEnumerable<string>)paths);
        }

        public static void FilesOrFolders(IEnumerable<string> paths)
        {
            if (paths == null) throw new ArgumentNullException("paths");

            FilesOrFolders(PathToFileSystemInfo(paths));
        }

        public static void FilesOrFolders(IEnumerable<FileSystemInfo> paths)
        {
            if (paths == null) throw new ArgumentNullException("paths");
            var pathsArray = paths.ToArray();
            if (pathsArray.Count() == 0) return;

            var explorerWindows = pathsArray.GroupBy(p => Path.GetDirectoryName(p.FullName));

            foreach (var explorerWindowPaths in explorerWindows)
            {
                var parentDirectory = Path.GetDirectoryName(explorerWindowPaths.First().FullName);
                FilesOrFolders(parentDirectory, explorerWindowPaths.Select(fsi => fsi.Name).ToList());
            }
        }
    }

    class Program
    {
        static void Main()
        {

            var test = 3;
            switch (test)
            {
                case 0:
                    var mydocs = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
                    ShowSelectedInExplorer.FileOrFolder(Path.Combine(mydocs, "Visual Studio 2010"), edit: true);

                    break;

                case 1:
                    ShowSelectedInExplorer.FileOrFolder(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile));
                    break;

                case 2:
                    ShowSelectedInExplorer.FilesOrFolders(@"C:\Windows\", new[] { "Microsoft.NET", "System32", "Setup" });
                    break;

                case 3:
                    ShowSelectedInExplorer.FilesOrFolders(@"C:\Windows\Microsoft.NET\", @"C:\Windows\System32", @"C:\Windows\Setup", @"C:\Program Files");
                    break;
            }
        }
    }
}

Autres conseils

Disclaimer: Je pense réponse de VirtualBlackFox est meilleure que la mienne même si elle a moins de voix à l'heure actuelle, donc défiler vers le bas et lire que une première:)

Méthode facile (ne fonctionne pas sur toutes les plateformes):

Process.Start(String, String)

Le premier argument est l'application, le deuxième argument est les paramètres de ligne de commande de l'application ..

Ainsi, par exemple:

Process.Start("explorer.exe",
"/select,Z:\Music\Thursday Blues\01. I wish it was friday.mp3")

Process.Start("explorer.exe",
"/select,Z:\Music\Counting Sheep\01. Sheep #1.mp3 /select,Z:\Music\Counting Sheep\02. Sheep #2.mp3")

(je pense que vous pourriez avoir besoin des citations échappées autour des chemins de fichiers s'ils ont des espaces).

Plus d'info: http://msdn.microsoft.com/en- nous / bibliothèque / h6ak8zt5.aspx

(compilé à partir des réponses à plusieurs href="https://stackoverflow.com/questions/334630/c-open-folder-and-select-the-file"> )


méthode plus difficile, mais plus susceptibles de travailler, provenant cette réponse à une autre question :

Utilisez la fonction d'enveloppe SHOpenFolderAndSelectItems

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

Essayez de commencer ceci:

explorer.exe /select,Z:\Music\Thursday Blues\01. I wish it was friday.mp3

Pour résumer : Il est impossible à l'aide Process.Start

De: -select-programatically plusieurs fichiers-en-explorateur Windows

réponse flashk de « Cela devrait être possible avec la fonction d'enveloppe SHOpenFolderAndSelectItems "me semble possible, mais je n'ai pas fatigué, il

  

Ceci est une vieille question, mais est venu   d'abord quand je googler similaire, donc   Je suis en train de faire la conclusion   plus facile à trouver.

Peut-être que vous pouvez utiliser ProcessExplorer pour savoir quels sont les arguments utilisés lorsque explorer.exe est lancé à partir de Media Player?

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