在WSL進行.Net 6 GUI專案的開發和USB的轉接
本篇主要記錄如何透過執行GUI應用程式(Avalonia)在WSL(Windows Subsystem for Linux)上,並能透過Visual Studio來Debug
基本上大部分步驟都參考這篇,如果看得懂英文能直接看這篇即可
本篇除了會講上述的議題外,還會講到如何讓WSL能抓到Windows上的USB裝置
安裝Linux在WSL上
首先打開Powershell,並執行以下指令
1 | wsl -- install -d Ubuntu |
如果是第一次使用WSL,應該會要求重啟電腦
想查看可安裝版本可以下
1 | wsl --list --online |
安裝其他指定版本,以安裝Debian為例
1 | wsl -- install -d Debian |
安裝完成後會要求輸入使用者名稱跟密碼,要離開可以輸入exit
要再次進入可以在Powershell輸入wsl
即可
進入Ubuntu之後,建議先輸入以下指令更新套件包,並安裝xterm
安裝xterm是為了下一個步驟測試用,非必要
1 | sudo apt-get update |
安裝VcXsvr
該程式能夠讓我們在Windows中開啟Linux的GUI應用程式
首先到該網頁下載並安裝
另外,聽說Windows 11不需要安裝該軟體,但我不確定
安裝完成後,可以找找一個叫XLaunch的程式,並將其開啟
之後依照下面的圖片設定Xlaunch
在右下角檢查有出現XLaunch的Icon就是有開啟成功了
測試執行Xterm
在Ubuntu上輸入以下指令開啟Xterm
1 | xterm |
結果應該會發現出現以下Error Message
1 | xterm: Xt error: Can't open display: |
主要是因為目前Ubuntu中沒有對DISPLAY進行設定
因此我們首先執行以下指令
1 | export DISPLAY=$(route.exe print | grep 0.0.0.0 | head -1 | awk '{print $4}'):0.0 |
結果會因人而異,而我的結果是
1 | 192.168.2.103:0.0 |
接下來可以直接執行剛剛開啟xterm的指令了
這時就會發現xterm的程式就出現在你Windows的桌面上了
使用Avalonia進行測試並Debug
首先將Avalonia的Demo專案Clone下來
1 | git clone https://github.com/npolyak/NP.Avalonia.Demos.git |
我們只會用到以下這兩個專案
- ConsoleAppForLinuxSubsystemDebuggingDemo
- AvaloniaAppForLinuxSubsystemDebuggingDemo
另外我們還需要安裝.Net 6的套件在Ubuntu上
1 | wget https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb |
在Console專案進行Debug
首先用Visual Studio打開ConsoleAppForLinuxSubsystemDebuggingDemo
我的VS是2022的版本
打開後在執行那列可以選擇要如何執行該專案,我們要將它改成WSL,如下圖
之後能將Break Point設定在任何地方進行Debug
以下是Break Point觸發和結果顯示
結果
1 | Yes, it is Linux!!! |
在GUI專案進行Debug
用Visual Studio打開AvaloniaAppForLinuxSubsystemDebuggingDemo
打開後如在Console專案一樣,改成用WSL執行
不同的是在要在Properties/launchSettings.json進行設定,將裡面的DISPLAY
屬性改成前面在Ubuntu設定的DISPLAY的值
1 | "DISPLAY": "192.168.2.103:0.0" |
之後執行,也一樣可以再任意地方加入Break Point來Debug,以下是執行結果
USB裝置接上WSL的Ubuntu
接下來要讓接在Windows上的USB裝置接到Ubuntu上
微軟在這部分也有文件能參考
首先有幾點條件要達成
- 作業系統要Windows 10以上
- 處理器要x64/86
- 需要WSL 2的Linux發行版
- Linux核心版本需高於或等於5.10.60.1
這邊不討論前兩點
使用WSL 2
在Powershell執行以下指令,可以顯示目前的Linux發行版是用WSL 1還是2
1 | wsl -l -v |
我的結果如下
1 | NAME STATE VERSION |
因為我的Ubuntu已經是使用WSL 2了,所以已經不用升級了
但若不是的話,需要執行以下指令來升級成WSL 2
1 | wsl --set-version <distro name> 2 |
所以以我的為例子,我得要執行以下指令來升級
1 | wsl --set-version Ubuntu 2 |
另外記得在升級前必須要將正在執行的Linux系統先關起來,指令如下
1 | wsl --shutdown |
升級Linux核心版本
首先在Ubnutu下執行以下指令確認核心版本
1 | uname -a |
我的結果如下
1 | Linux DESKTOP-S9T9GJ3 5.10.16.3-microsoft-standard-WSL2 #1 SMP Fri Apr 2 22:23:49 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux |
版本是5.10.16.3,比5.10.60.1還低,因此得要升級Linux核心版本
可以透過以下指令達成,他會將WSL 2進行更新,一樣要先將Linux系統先關掉
1 | wsl --update |
這時候再去下uname -a
,會發現Linux核心已經升級
1 | Linux DESKTOP-S9T9GJ3 5.10.102.1-microsoft-standard-WSL2 #1 SMP Wed Mar 2 00:30:59 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux |
安裝必須套件和軟體
在條件都達成後,我們還需要在Windows和Linux裡面都安裝必要的軟體
首先是Ubuntu那邊
先執行以下指令安裝需要的套件
1 | sudo apt install linux-tools-5.4.0-77-generic hwdata |
接下來是Windows的部分,到該網站下載並安裝usbipd-win,下載msi檔即可
下載或安裝過程可能會告知有風險之類的,不用管
安裝完成後,在cmd執行以下指令取得目前的所有USB裝置
1 | usbipd wsl list |
我的結果如下
1 | BUSID VID:PID DEVICE STATE |
我這邊想讓3-2這個BUS接到Ubuntu上,透過以下指令能達成
1 | usbipd wsl attach --busid 3-2 |
這時候執行usbipd wsl list
可以看到3-2的狀態已經是Attached了
1 | BUSID VID:PID DEVICE STATE |
另外如果要拔掉的話,執行以下指令來Detach
1 | usbipd wsl detach --busid 3-2 |
接下來跳到Ubuntu那邊,執行以下指令來確認是否有接上
1 | lsusb |
我的結果如下
1 | Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub |
第二個就是我想接上的Device
其他
.Net 6要取得USB裝置,應該會需要用到System.IO.Ports的套件,又或是其他人已經寫好的套件
另外還要注意的是,要存取USB裝置會遇到權限問題,不想搞太麻煩,方便為主的話可以到/dev
找對應的Port,並修改權限
可以執行以下指令來獲得最近插入的Port來得知你插入的裝置是在哪個Port
1 | dmesg | grep tty |
後記
由於工作上需要用.Net 6開發Linux的GUI應用程式和操控硬體,所以才會寫本篇做記錄
目前正在研究有沒有辦法透過使用Vendor ID或Device ID來取得對應的Port,如果有結果的話會再更新
2022/05/31更新
下面的Code主要是透過下Command的方式,透過Vendor Id和Product Id來取得對應的Device
1 | using System.IO.Ports; |