partes - C#: Cómo abrir las ventanas del Explorador de Windows con una serie de archivos seleccionados
partes del explorador de windows 10 (5)
¿Quizás pueda usar ProcessExplorer para averiguar qué argumentos se usan cuando se ejecuta explorer.exe desde Media Player?
Saludos,
Sebastiaan
En la Biblioteca del Reproductor de Windows Media, puede seleccionar uno o más archivos de música. A continuación, puede hacer clic con el botón derecho y, en su menú contextual, elegir Abrir ubicación de archivo . Esto abrirá una ventana de Windows Explorer para cada directorio en el que se encuentran los archivos, y los archivos se seleccionarán para usted.
Entonces, digamos que tenemos un montón de archivos mp3 en nuestra biblioteca donde tres de ellos son estos:
- Z: / Music / Thursday Blues / 01. Ojalá fuera viernes.mp3
- Z: / Music / Counting Sheep / 01. Ovejas # 1.mp3
- Z: / Music / Counting Sheep / 02. Ovejas # 2.mp3
Si seleccionamos esos tres (en una vista donde todos están visibles) y hacemos Abrir la ubicación del archivo, aparecerán dos ventanas del explorador. Una será la carpeta Z: / Music / Thursday Blues con 01. Me gustaría que fuera friday.mp3 seleccionado, y la otra será la carpeta * Z: / Music / Counting Sheep ** con ambas 01. Sheep # 1. mp3 y 02. Sheep # 2.mp3 seleccionado.
¿Cómo puedo hacer esto yo mismo en C #? Tenemos una aplicación que va a exportar datos a varios formatos, por ejemplo, CSV y Excel, y me gustaría abrir las ventanas del explorador con estos archivos seleccionados cuando se crean y están listos para ser vistos. Actualmente, solo hago Process.Start(path)
, y esto funciona, pero me encantaría poder resaltar esos archivos en particular también. Haría los archivos que fueron creados mucho más obvios.
Windows Media Player lo hace muy bien ... Quiero hacerlo también = / ¿Hay algún empleado de Microsoft aquí que pueda averiguar cómo se puede hacer? (UNA)
Buscando una respuesta después de que un compañero de trabajo tuvo el problema, no encontré ninguno, así que escribí una pequeña clase para hacer esto. El código está en Gist y pegaré la versión actual al final de esta publicación.
Con sus archivos de muestra, la sintaxis será:
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"
);
Hay algunas limitaciones en mi código en comparación con la API de bajo nivel, principalmente:
- La selección en el escritorio no está implementada.
- El directorio principal debe ser un directorio o una unidad, por lo que no puede seleccionar varias unidades en la carpeta Mi PC, por ejemplo.
De todos modos, aquí está el código fuente de la clase 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;
}
}
}
}
Intenta empezar esto:
explorer.exe /select,Z:/Music/Thursday Blues/01. I wish it was friday.mp3
Descargo de responsabilidad: creo que la respuesta de VirtualBlackFox es mejor que la mía, aunque actualmente tiene menos votos, así que desplácese hacia abajo y lea eso primero :)
Método fácil (podría no funcionar en todas las plataformas):
Process.Start(String, String)
El primer argumento es la aplicación, el segundo argumento son los parámetros de la línea de comandos de la aplicación.
Así por ejemplo:
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")
(Creo que es posible que necesite comillas de escape en las rutas de los archivos si tienen espacios).
más información: http://msdn.microsoft.com/en-us/library/h6ak8zt5.aspx
(compilado de varias respuestas a esta pregunta )
El método más difícil, pero es más probable que funcione, tomado de esta respuesta a otra pregunta :
Utilice la función de shell http://msdn.microsoft.com/en-us/library/h6ak8zt5.aspx
Aquí hay un código de ejemplo que muestra cómo usar la función en C / C ++, sin comprobación de errores:
//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);
Para resumir : No es posible usar Process.Start
Desde: programatically-select-multiple-files-in-windows-explorer
La respuesta de flashk de "Esto debería ser posible con la función de shell SHOpenFolderAndSelectItems
" me parece posible, pero no la he cansado.
Esta es una pregunta antigua, pero surgió primero cuando buscaba en Google de forma similar, así que estoy tratando de hacer que la conclusión sea más fácil de encontrar.