WPF 已知問題 監聽 WMI 事件導致觸控失效

lindexi發表於2024-09-11

本文記錄 WPF 的已知問題,在 .NET Core 版本的 WPF 應用裡面,應用啟動的過程監聽 WMI 事件,將導致觸控模組 COM 介面獲取失敗,進而導致觸控失效

此問題僅在 .NET Core 版本復現,在 .NET Framework 框架下能正常工作

復現步驟如下:

  1. 安裝 System.Management 庫用於使用 WqlEventQuery 監聽 WMI 變更
  2. 監聽 TouchDown 事件輸出斷點資訊

復現程式碼如下

    public MainWindow()
    {
        InitializeComponent();

        AppDomain.CurrentDomain.FirstChanceException += (sender, args) =>
        {
            Debug.WriteLine(args.Exception);
        };

        WqlEventQuery insertQuery =
            new WqlEventQuery("SELECT * FROM __InstanceCreationEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_USBHub'");
        ManagementEventWatcher insertWatcher = new ManagementEventWatcher(insertQuery);
        insertWatcher.Start(); // 如果註釋掉這句話,那 TouchDown 事件將會被觸發

        TouchDown += MainWindow_TouchDown;
    }

    private void MainWindow_TouchDown(object? sender, TouchEventArgs e)
    {
        Debugger.Break(); // 不會被命中
    }

加上 insertWatcher.Start() 這句程式碼時,可以從 FirstChanceException 看到如下異常

System.InvalidCastException: 沒有註冊介面


   at MS.Win32.Penimc.UnsafeNativeMethods.CoCreateInstance(Guid& clsid, Object punkOuter, Int32 context, Guid& iid)

此問題已經報告給 WPF 官方,請看 https://github.com/dotnet/wpf/issues/9752

本文程式碼放在 githubgitee 上,可以使用如下命令列拉取程式碼。我整個程式碼倉庫比較龐大,使用以下命令列可以進行部分拉取,拉取速度比較快

先建立一個空資料夾,接著使用命令列 cd 命令進入此空資料夾,在命令列裡面輸入以下程式碼,即可獲取到本文的程式碼

git init
git remote add origin https://gitee.com/lindexi/lindexi_gd.git
git pull origin 308096e0c8ede019f6dbe5bfe974ae1a12d7de42

以上使用的是國內的 gitee 的源,如果 gitee 不能訪問,請替換為 github 的源。請在命令列繼續輸入以下程式碼,將 gitee 源換成 github 源進行拉取程式碼。如果依然拉取不到程式碼,可以發郵件向我要程式碼

git remote remove origin
git remote add origin https://github.com/lindexi/lindexi_gd.git
git pull origin 308096e0c8ede019f6dbe5bfe974ae1a12d7de42

獲取程式碼之後,進入 WPFDemo/YanerehaylemJeekalhebel 資料夾,即可獲取到原始碼

更多技術部落格,請參閱 部落格導航

相關文章