用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
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...