用WindowsAppSDK(WASDK)優雅的開發上位機應用

来源:https://www.cnblogs.com/GreenShade/archive/2022/06/28/16419420.html
-Advertisement-
Play Games

C#開發上位機應用的一些選擇 如果你不想看介紹,可以直接跳到優雅開發示例那裡。 1. WASDK(WinUI 3) Windows 應用 SDK 是一組新的開發人員組件和工具,它們代表著 Windows 應用開發平臺的下一步發展。 Windows 應用 SDK 提供一組統一的 API 和工具,可供從 ...


C#開發上位機應用的一些選擇

如果你不想看介紹,可以直接跳到優雅開發示例那裡。

1. WASDK(WinUI 3)

Windows 應用 SDK 是一組新的開發人員組件和工具,它們代表著 Windows 應用開發平臺的下一步發展。 Windows 應用 SDK 提供一組統一的 API 和工具,可供從 Windows 11 到 Windows 10 版本 1809 上的任何桌面應用以一致的方式使用。

Windows 應用 SDK 不會用 C++ 替換 Windows SDK 或現有桌面 Windows 應用類型,例如 .NET(包括 Windows 窗體和 WPF)和桌面 Win32。 相反,Windows 應用 SDK 使用一組通用 API 來補充這些現有工具和應用類型,開發人員可以在這些平臺上依賴這些 API 來執行操作。 有關更多詳細信息,請參閱Windows 應用 SDK 的優勢。

這個WASDK目前是微軟主推的開源的,UI部分是結合了WinUI 3。

2. WPF

歡迎使用 Windows Presentation Foundation (WPF) 桌面指南,這是一個與解析度無關的 UI 框架,使用基於矢量的呈現引擎,構建用於利用現代圖形硬體。 WPF 提供一套完善的應用程式開發功能,這些功能包括 Extensible Application Markup Language (XAML)、控制項、數據綁定、佈局、二維和三維圖形、動畫、樣式、模板、文檔、媒體、文本和版式。 WPF 屬於 .NET,因此可以生成整合 .NET API 其他元素的應用程式。

目前WPF也已經開源,而且整體上更為成熟,Visual Studio就是WPF 4.x開發的,生態也比較好。

3. WinForms

歡迎使用 Windows 窗體的桌面指南,Windows 窗體是一個可創建適用於 Windows 的豐富桌面客戶端應用的 UI 框架。 Windows 窗體開發平臺支持廣泛的應用開發功能,包括控制項、圖形、數據綁定和用戶輸入。 Windows 窗體採用 Visual Studio 中的拖放式可視化設計器,可輕鬆創建 Windows 窗體應用。

這個也是開源的,Winform算是上手即用的開發框架了,通過拖拉拽可以很輕鬆的創建出UI和編寫對應的功能,對於UI美觀程度不太重要的工業領域,這個用來做工具開發很簡單,上手也容易。

4. UWP

UWP 是創建適用於 Windows 的客戶端應用程式的眾多方法之一。 UWP 應用使用 WinRT API 來提供強大的 UI 和高級非同步功能,這些功能非常適用於 Internet 連接的設備。

微軟對於UWP,只能說曾經愛過,當初UWP可是當紅炸子雞,號稱跨windows全平臺,不過現在也是跨windows全平臺,可惜沒搞好,不過雖然不夠受重視,但是一時半會還是死不掉,畢竟WASDK還不夠成熟。

為什麼選擇WASDK

通過上面的介紹,大家對於windows下的原生UI開發框架應該有了一些瞭解,如果拋開語言限制的話還有更多的選擇,比如QT,各種前端的跨平臺,像微軟自己家的MAUI什麼的,我之前還寫了一篇WinUI遷移到即將"過時"的.NET MAUI個人體驗

最近的微軟Windows App SDK 1.1版本發佈了,意味著BUG應該少了很多,也可以正式的在一些項目中使用了。通過官方的WinUI庫,我們可以輕鬆的構建符合Win11設計規範的UI,由於UWP的種種問題,WPF和WinForms又是只開源,應該不會有大的新特性了,外加本人以前也經常玩玩UWP,通過前景和自己的喜好,肯定是選擇WASDK了。

優雅開發示例

1. 做一個上位機應用

上位機示例圖
上圖為應用的展示圖,採用的WASDK1.1版本開發,目前已經上架了Windows商店,打包方式為MSIX,目前x64和arm64是分開的MSIX包,文檔里提到可以多個MSIX包合成一個集合包,不過我採用上傳多個包,讓商店自動匹配。

此應用是為稚暉君的ElectronBot開發的第三方的上位機,名字就叫電子腦殼。下圖是效果圖展示,結合Surface平板,觸摸體驗良好,個人感覺很優雅。

實物控制

B站演示視頻

2. 整體的開發步驟

ElectronBot本身連接電腦採用的是libusb生成的驅動吧,這個不知道敘述的是否正確。

看下圖大體能明白電腦和ElectronBot通過高速USB進行連接,當我們驅動安裝成功就可以進行操作了。

img

電子腦殼應用=>ElectronBot.DotNet SDK=>LibUsbDotNet

底層調用採用的是LibUsbDotNet這個庫進行底層數據傳輸的操作,我根據稚暉君提供的c++版本的sdk進行了封裝。

目前c#版本的SDKElectronBot.DotNet是開源的,demo示例也是windowsAppSDK的,大家感興趣的可以star一下。

開始創建項目前最好安裝下Template Studio for WinUI

img

2.1 創建項目

img

選擇模板進行創建,可以根據需要進行選擇,本人選擇如下。
img

由於ElectronBot .Net SDK本身已經開源,直接以上位機主體應用做講解。下圖為應用的依賴項,主要包含SDK和OpenCV相關的nuget包。

應用依賴項

應用整體不複雜,通過.Net框架自帶的DI容器進行對象生命周期的管理,通過MVVM進行數據的綁定和更新。

結合Win2D和OpenCV進行圖形數據處理,然後通過SDK寫入到usb設備里進行控制和展示。

軟體整體的實現邏輯

2.2 關鍵點代碼講解

下麵的代碼是通過切換Combox事件,動態創建不同的表盤並綁定到MainWindows的控制項上。

private ICommand _clockChangedCommand;
public ICommand ClockChangedCommand => 
    _clockChangedCommand ?? (_clockChangedCommand = new RelayCommand(ClockChanged));

private async void ClockChanged()
{
    var clockName = _clockComboxSelect.DataKey;

    if (!string.IsNullOrWhiteSpace(clockName))
    {
        var viewProvider = _viewProviderFactory.CreateClockViewProvider(clockName);

        Element = viewProvider.CreateClockView(clockName);
    }

    await Task.CompletedTask;
}

public UIElement Element
{
    get => _element;
    set => SetProperty(ref _element, value);
}

xaml代碼如下。

img

通過此操作,能夠正常顯示表盤,數據刷新也能正常使用。

當切換到時鐘模式的時候,另外一個定時器會定時抓取表盤並將xaml轉化成圖片進行傳輸,主要涉及到Win2D庫的使用,代碼如下。

if (_electron.Connect())
{
    var bitmap = new RenderTargetBitmap();
    await bitmap.RenderAsync(Element);
    var pixels = await bitmap.GetPixelsAsync();

    // Transfer the pixel data from XAML to Win2D for further processing.
    using CanvasDevice canvasDevice = CanvasDevice.GetSharedDevice();

    using CanvasBitmap canvasBitmap = CanvasBitmap.CreateFromBytes(
        canvasDevice, pixels.ToArray(), bitmap.PixelWidth, bitmap.PixelHeight, 
        Windows.Graphics.DirectX.DirectXPixelFormat.B8G8R8A8UIntNormalized);

    using IRandomAccessStream stream = new InMemoryRandomAccessStream();

    await canvasBitmap.SaveAsync(stream, CanvasBitmapFileFormat.Png);

    Bitmap image = new Bitmap(stream.AsStream());

    var mat = OpenCvSharp.Extensions.BitmapConverter.ToMat(image);

    var mat1 = mat.Resize(new OpenCvSharp.Size(240, 240), 0, 0, OpenCvSharp.InterpolationFlags.Area);

    var mat2 = mat1.CvtColor(OpenCvSharp.ColorConversionCodes.RGBA2BGR);

    var dataMeta = mat2.Data;

    var data = new byte[240 * 240 * 3];

    Marshal.Copy(dataMeta, data, 0, 240 * 240 * 3);

    await Task.Run(() =>
    {
        if (_electron.Connect())
        {
            _electron.SetImageSrc(data);

            _electron.Sync();
        }
    });


}

上面代碼通過RenderTargetBitmap和Win2D將Xaml元素轉化成CanvasBitmap,然後再通過OpenCV將canvasBitmap轉化成下位機可識別的位元組數組,通過SDK進行傳輸到下位機。

整體的開發過程和UWP很相似,UI部分用到的很多API都是UWP的改名版本,上位機目前沒有開源,所以只能截取部分代碼進行講解了,如果想交流大家可以評論區見。

3. 遇到的一些問題

目前Windows App SDK有一些BUG,在我使用的過程中主要發現使用WinRT的串口監聽事件失效,已在github提了bug,回頭應該能夠修複,還有WinRT里的一些API只認UWP UI Api windows.UI開頭的一些對象,還需要大家多使用多反饋,這樣WASDK開發才能良性迴圈。

public async Task InitAsync()
{
    // Target all Serial Devices present on the system
    var deviceSelector = SerialDevice.GetDeviceSelector();

    var myDevices = await Windows.Devices.Enumeration.DeviceInformation.FindAllAsync(deviceSelector);

    deviceWatcher = DeviceInformation.CreateWatcher(deviceSelector);

    deviceWatcher.Added += new TypedEventHandler<DeviceWatcher, DeviceInformation>(this.OnDeviceAdded);
    deviceWatcher.Removed += new TypedEventHandler<DeviceWatcher, DeviceInformationUpdate>(this.OnDeviceRemoved);

}

上面代碼註冊的事件,在目前1.1版本的WASDK不生效,官方已經標註為BUG,當然在UWP里就正常,UWP在有些時候還是挺靠譜的嘛。

個人總結感悟

通過這個上位機應用的開發,也是對WASDK和UWP相關技術的使用能熟練一些了,從WPF到UWP再到WASDK和MAUI,XAML相關的開發都是可繼承的,開發方式很相似,對於技術的遷移來說也算是沒什麼障礙吧,經常會聽到很多人說微軟出了這麼多技術,都學不動了什麼的,其實大家掌握內涵,對於新技術的接受還是很快的。

特別鳴謝以及參考推薦文檔

感謝dino.c大佬的一個番茄鐘,因為我的表盤其實就是抄他番茄鐘的代碼。

感謝h哥火火給的一些思路。

當然還要感謝超超,畢竟有些代碼還是抄他的。

參考推薦文檔如下

一個番茄鐘

Win2D samples

opencvsharp

WindowsAppSDK

WindowsCommunityToolkit

ElectronBot

ElectronBot.DotNet

LibUsbDotNet


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 使用 Java 編譯項目時產生的報錯 java: Compilation failed: internal java compiler error 錯誤原因 導致這個錯誤的原因主要有三點: 編譯版本不匹配 JDK 版本不支持 記憶體不足 解決辦法 對於編譯版本不匹配,我們要先查看 IDEA 的編譯的 ...
  • 前言 嗨嘍,大家好!這裡是魔王吶~ 環境使用: Python 3.8 解釋器<運行代碼> Pycharm 編輯器 <寫代碼> 模塊使用]: requests >>> 數據請求 第三方模塊 pip install requests <工具> re <正則表達式模塊> 如果安裝python第三方模塊: ...
  • ​一、4數種類分析 統計分析 從標有1-10的數字的10個小球中取出1個小球記錄小球的數字,然後將小球放回,如此反覆4次取出4小球的數字組成的序號一共有多少種。註意:1.1.8.9 和1.8.1.9 算是一種。 需要分為一下幾種情況: 四個小球數字都相等情況: 一個有10種 三個小球數字相等: 一共 ...
  • 目錄 一.簡介 二.效果演示 三.源碼下載 四.猜你喜歡 零基礎 OpenGL (ES) 學習路線推薦 : OpenGL (ES) 學習目錄 >> OpenGL ES 基礎 零基礎 OpenGL (ES) 學習路線推薦 : OpenGL (ES) 學習目錄 >> OpenGL ES 轉場 零基礎 O ...
  • spring框架應用的是ioc模式,ioc模式是指控制反轉模式,本質是你不去創建對象讓spring框架給你創建對象你去使用對象。多種開發模式通過配置文件和註解的方式去開發的都很值得去學習 ...
  • 前言 嗨嘍,大家好呀!這裡是魔王吶~ 環境使用: Python 3.8 Pycharm 模塊使用: requests >>> pip install requests 數據請求模塊 parsel >>> pip install parsel 數據解析模塊 csv 內置模塊 如果安裝python第三方 ...
  • 正所謂“工欲善其事、必先利其器”,面對一個優秀的框架,如果再結合一些外部的工具,其實可以讓我們的開發效率與程式員開發過程的體驗更上一層樓的。 ...
  • Set數據結構 使用 intset 當同時滿足下麵兩個條件時,使用 intset 存儲數據 元素個數少於512個 (set-max-intset-entries: 512) 所有元素都是整數值 不滿足上面的條件, 使用 hashtable intset 圖解 //intset 的編碼方式 #defi ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...