本文告訴大家在 dotnet 5 里,如何使用 WinRT 加上 Microsoft.Windows.SDK 的輔助來調用 WindowsRuntime 方法。當前是 2021.10 此時的 Windows App SDK 還沒准備好,也因此構建起來等邏輯都有點鍋。本文和大家演示如何在 WPF 應用里面用上 UWP 提供的 FolderPicker 類型
需要將原有的基於 .NET 5 的 WPF 應用的 csproj 替換 net5.0-windows
為 net5.0-windows10.0.19041.0
代碼如下
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<UseWPF>true</UseWPF>
<TargetFramework>net5.0-windows10.0.19041.0</TargetFramework>
</PropertyGroup>
</Project>
以上表示采用 10.0.19041.0 的 SDK 版本,更多可用的版本請參閱 CsWinRT/authoring.md at master · microsoft/CsWinRT
當前有以下的 SDK 可用
- net5.0-windows10.0.17763.0
- net5.0-windows10.0.18362.0
- net5.0-windows10.0.19041.0
- net5.0-windows10.0.20348.0
- net6.0-windows10.0.17763.0
- net6.0-windows10.0.18362.0
- net6.0-windows10.0.19041.0
- net6.0-windows10.0.20348.0
我當前也理不清 CsWinRT 和 Windows App SDK 等倉庫和技術線的關系,請不要問我為什么會碰到這些倉庫
接下來需要在 cs 代碼里面定義一個 COM 接口,通過此接口進行初始化。盡管官方文檔說可以使用 WinRT.Interop.InitializeWithWindow.Initialize
方法進行初始化,然而實際上我沒有找到此 InitializeWithWindow 類型。好在這些都是 COM 接口,可以自己定義,代碼如下
[ComImport]
[Guid("3E68D4BD-7135-4D10-8018-9FB6D9F33FA1")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IInitializeWithWindow
{
void Initialize(IntPtr hwnd);
}
以上接口是通過 Pin secondary tiles from desktop apps - Windows apps 文檔了解的
先創建 FolderPicker 對象
var folderPicker = new Windows.Storage.Pickers.FolderPicker();
folderPicker.FileTypeFilter.Add("*");
接着將當前的窗口給到 FolderPicker 對象,讓這個對象可以作為窗口的模態
var hwnd = System.Diagnostics.Process.GetCurrentProcess().MainWindowHandle; //WinRT.Interop.WindowNative.GetWindowHandle(this);
//WinRT.Interop.InitializeWithWindow.Initialize(folderPicker, hwnd);
//IInitializeWithCoreWindow initializeWithCoreWindow;// 這個不能使用
var initializeWithCoreWindow = folderPicker.As<IInitializeWithWindow>();
initializeWithCoreWindow.Initialize(hwnd);
接下來就可以和 UWP 一樣使用 FolderPicker 讓用戶選擇文件夾
var folder = await folderPicker.PickSingleFolderAsync();
Debug.WriteLine(folder.Path);
使用本文的方法,應用是不需要進行打包為 MSIX 包在用戶端進行部署就可以使用,雙擊 exe 就可以使用,和之前的相同。因為調用 WindowsRuntime 的原理是 COM 調用,不需要進行打包
可以通過如下方式獲取本文代碼
先創建一個空文件夾,接着使用命令行 cd 命令進入此空文件夾,在命令行里面輸入以下代碼,即可獲取到本文的代碼
git init
git remote add origin https://gitee.com/lindexi/lindexi_gd.git
git pull origin 26b7b6eec1f8e734bb9dbd49447f62fe2e116a9c
以上使用的是 gitee 的源,如果 gitee 不能訪問,請替換為 github 的源
git remote remove origin
git remote add origin https://github.com/lindexi/lindexi_gd.git
獲取代碼之后,進入 WelhearyalluneaceKujalwhekiraqi 文件夾
大概可以從 Breaking change: Built-in support for WinRT is removed from .NET 文檔了解到為什么在 .NET 5 需要用到 CsWinRT 的原因