gpt4 book ai didi

C#:如何打开选择了多个文件的 Windows 资源管理器窗口

转载 作者:IT王子 更新时间:2023-10-29 04:32:13 28 4
gpt4 key购买 nike

在 Windows Media Player 的媒体库中,您可以选择一个或多个音乐文件。然后您可以右键单击并在上下文菜单中选择打开文件位置。这将为文件所在的每个目录打开一个 Windows 资源管理器窗口,并为您选择文件。

假设我们的库中有一堆 mp3 文件,其中三个是:

  • Z:\Music\Thursday Blues\01。我希望是星期五.mp3
  • Z:\Music\Counting Sheep\01。绵羊#1.mp3
  • Z:\Music\Counting Sheep\02.绵羊#2.mp3

如果我们选择这三个(在所有这些都可见的 View 中)并执行打开文件位置,那么将弹出两个资源管理器窗口。一个是带有 01 的 Z:\Music\Thursday Blues 文件夹。我希望它是 friday.mp3 被选中,另一个将是 *Z:\Music\Counting Sheep** 文件夹,同时 01。绵羊 #1.mp302。绵羊 #2.mp3 已选中。

我如何在 C# 中自己完成此操作?我们有一个应用程序将数据导出为各种格式,例如 CSV 和 Excel,我想打开资源管理器窗口,并在创建这些文件并准备好查看它们时将其选中。目前我只是执行 Process.Start(path),这很有效,但我也希望能够突出显示那些特定的文件。会使刚刚创建的文件更加明显。


Windows Media Player 做的真好...我也想做 =/这里有任何 Microsoft 员工可以弄清楚如何完成吗? (一)

最佳答案

在一位同事遇到问题后寻找答案,但我没有找到答案,所以我写了一个小类来做这个。代码is on Gist我将在本文末尾粘贴当前版本。

对于您的示例文件,语法将是:

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

与低级 API 相比,我的代码有一些限制,主要是:

  • 桌面上的选择没有实现
  • 父目录必须是目录或驱动器,因此您不能在“我的电脑”文件夹中选择多个驱动器。

无论如何,这是 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;
}
}
}
}

关于C#:如何打开选择了多个文件的 Windows 资源管理器窗口,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1073353/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com