打开资源管理器且选中某个文件可以使用 cmd 调用 explorer 带上 select 参数,如下面命令行所示
explorer.exe /select,"C:\Folder\file.txt"
但有很多情况下,用户可能使用其他资源管理器,此时将会导致应用软件打开的是 explorer 而不是用户默认的资源管理器
通过 shell32.dll 提供的 SHOpenFolderAndSelectItems 方法,可以直接使用函数调用的方式打开资源管理器且选中某个文件,且使用的是用户设置的默认的资源管理器
以下是我创建的简单的 WPF 例子程序的界面,可以看到界面非常简单,就是输入一个文件,然后点击按钮就可以打开资源管理器选中输入的文件
<Grid>
<Grid VerticalAlignment="Center">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Text="文件路径:" Margin="50,0,0,0" VerticalAlignment="Center"/>
<TextBox x:Name="InputTextBox" Grid.Column="1" Margin="10,0,10,0" VerticalAlignment="Center"/>
<Button Grid.Column="2" Content="打开" Margin="10,0,50,0" VerticalAlignment="Center" Click="Button_OnClick"/>
</Grid>
</Grid>
按钮的后台代码将需要使用 PInvoke 调用 Win32 函数。对于 dotnet 7 以前的程序,可使用如下方式定义
[DllImport("shell32.dll", ExactSpelling = true)]
private static extern void ILFree(IntPtr pidlList);
[DllImport("shell32.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
private static extern IntPtr ILCreateFromPathW(string pszPath);
[DllImport("shell32.dll", ExactSpelling = true)]
private static extern int SHOpenFolderAndSelectItems(IntPtr pidlList, uint cild, IntPtr children, uint dwFlags);
对于 dotnet 7 以及更高版本的项目,可使用 LibraryImportAttribute 特性辅助定义。如以下 C# 代码所示
[LibraryImport("shell32.dll")]
private static partial void ILFree(IntPtr pidlList);
[LibraryImport("shell32.dll", StringMarshalling = StringMarshalling.Utf16)]
private static partial IntPtr ILCreateFromPathW(string pszPath);
[LibraryImport("shell32.dll")]
private static partial int SHOpenFolderAndSelectItems(IntPtr pidlList, uint cild, IntPtr children, uint dwFlags);
过程中别忘了在 csproj 项目文件里面开启不安全代码,开启之后的项目文件代码大概如下
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net9.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<UseWPF>true</UseWPF>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
</PropertyGroup>
</Project>
后台 C# 代码的按钮点击事件里面将调用 SHOpenFolderAndSelectItems 方法打开资源管理器选中输入的文件
private void Button_OnClick(object sender, RoutedEventArgs e)
{
var filePath = InputTextBox.Text;
filePath = System.IO.Path.GetFullPath(filePath);
IntPtr pidlList = ILCreateFromPathW(filePath);
if (pidlList != IntPtr.Zero)
{
try
{
Marshal.ThrowExceptionForHR(SHOpenFolderAndSelectItems(pidlList, 0, IntPtr.Zero, 0));
}
finally
{
ILFree(pidlList);
}
}
}
以上代码里面的 ILCreateFromPathW 要求传入绝对路径,需要调用 System.IO.Path.GetFullPath
方法转换传入路径为绝对路径
如果不知道代码如何写的话,可以拉取我的例子项目代码跑跑看
本文代码放在 github 和 gitee 上,可以使用如下命令行拉取代码。我整个代码仓库比较庞大,使用以下命令行可以进行部分拉取,拉取速度比较快
先创建一个空文件夹,接着使用命令行 cd 命令进入此空文件夹,在命令行里面输入以下代码,即可获取到本文的代码
git init
git remote add origin https://gitee.com/lindexi/lindexi_gd.git
git pull origin 6988631e41226832c3b83cf62529eb7d7892e0b2
以上使用的是国内的 gitee 的源,如果 gitee 不能访问,请替换为 github 的源。请在命令行继续输入以下代码,将 gitee 源换成 github 源进行拉取代码。如果依然拉取不到代码,可以发邮件向我要代码
git remote remove origin
git remote add origin https://github.com/lindexi/lindexi_gd.git
git pull origin 6988631e41226832c3b83cf62529eb7d7892e0b2
获取代码之后,进入 WPFDemo/WilinojearcheWheyecearhire 文件夹,即可获取到源代码
更多 WPF 博客,请参阅 博客导航
参考文档
c# - How to open Explorer with a specific file selected? - Stack Overflow
file - C#: How to use SHOpenFolderAndSelectItems - Stack Overflow
SHOpenFolderAndSelectItems 函数 (shlobj_core.h) - Win32 apps - Microsoft Learn
【C#】在Windows资源管理器打开文件夹,并选中指定的文件或文件夹 - Tod's - 博客园
标签:IntPtr,git,pidlList,代码,器且,shell32,WPF,资源管理 From: https://www.cnblogs.com/lindexi/p/18548977