開啟資源管理器且選中某個檔案可以使用 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
c#: 開啟資料夾並選中檔案 - 楚人無衣 - 部落格園
SHOpenFolderAndSelectItems 函式 (shlobj_core.h) - Win32 apps - Microsoft Learn
【C#】在Windows資源管理器開啟資料夾,並選中指定的檔案或資料夾 - Tod's - 部落格園