1. 程式人生 > 其它 >dotnet 5 讓 WPF 呼叫 WindowsRuntime 方法

dotnet 5 讓 WPF 呼叫 WindowsRuntime 方法

本文告訴大家在 dotnet 5 裡,如何使用 WinRT 加上 Microsoft.Windows.SDK 的輔助來呼叫 WindowsRuntime 方法。當前是 2021.10 此時的 Windows App SDK 還沒準備好,也因此構建起來等邏輯都有點鍋。本文和大家演示如何在 WPF 應用裡面用上 UWP 提供的 FolderPicker 型別

本文告訴大家在 dotnet 5 裡,如何使用 WinRT 加上 Microsoft.Windows.SDK 的輔助來呼叫 WindowsRuntime 方法。當前是 2021.10 此時的 Windows App SDK 還沒準備好,也因此構建起來等邏輯都有點鍋。本文和大家演示如何在 WPF 應用裡面用上 UWP 提供的 FolderPicker 型別

需要將原有的基於 .NET 5 的 WPF 應用的 csproj 替換 net5.0-windowsnet5.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 呼叫,不需要進行打包

本文所有程式碼放在 githubgitee 歡迎訪問

可以通過如下方式獲取本文程式碼

先建立一個空資料夾,接著使用命令列 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 的原因

部落格園部落格只做備份,部落格釋出就不再更新,如果想看最新部落格,請到 https://blog.lindexi.com/


本作品採用知識共享署名-非商業性使用-相同方式共享 4.0 國際許可協議進行許可。歡迎轉載、使用、重新發布,但務必保留文章署名[林德熙](http://blog.csdn.net/lindexi_gd)(包含連結:http://blog.csdn.net/lindexi_gd ),不得用於商業目的,基於本文修改後的作品務必以相同的許可釋出。如有任何疑問,請與我[聯絡](mailto:[email protected])。