65.9K
CodeProject 正在变化。 阅读更多。
Home

在 Windows Subsystem for Linux (WSL) 上运行和调试跨平台 .NET (.NET Core, .NET5 和 .NET6) GUI 和控制台应用程序

starIconstarIconstarIconstarIconstarIcon

5.00/5 (22投票s)

2022 年 4 月 24 日

CPOL

9分钟阅读

viewsIcon

32389

本文介绍如何使用 WSL 测试和调试 .NET/Avalonia Linux 应用程序。

请求投票和评论

朋友们,我注意到很多人在阅读这篇文章,有些告诉我或以某种方式表明他们喜欢它,但很少有人投票。请投票并写下评论,告诉我您对这篇文章的喜好和不喜欢之处,以便我改进文章写作技巧。谢谢!

本文内容概要

.NET Standard, CORE .NET5 和 .NET6 使 .NET 实现了跨平台(GUI 程序除外)。Avalonia 填补了这一空白,使得也可以在 .NET 中开发跨平台 GUI 程序。

WSL2 - Windows Subsystem for Linux 的最新版本,允许直接在 Windows 上测试 Linux 程序(包括用 .NET 和 Avalonia 开发的程序)(无需将其移动到 Linux 计算机或虚拟机)。

最后,Visual Studio 2022 可以在 Windows 上调试用 .NET 和 Avalonia 开发的 Linux 程序,无需将其移动到任何地方。

本文详细介绍了如何正确安装和使用 Microsoft 包和 Avalonia 的这一强大组合,以便在 Visual Studio 2022 中开发 Linux .NET Core 应用程序时进行调试。

本文使用的操作系统和软件包

Windows 最新版本(10 和 11)允许在 Windows 平台上运行 Linux 系统。这非常方便,尤其是在使用 Visual Studio 在 Windows 上构建跨平台或 Linux 特定的程序进行测试和调试时。

我特别对使用新的开源 .NET 版本(.NET STANDARD、.NET CORE、.NET5 和 .NET6)构建的跨平台控制台和 GUI 应用程序感兴趣。

上面列出的所有 .NET 版本除了用于构建桌面 UI 应用程序的库(WPF 和 WinForms)之外,都是跨平台的。这就是用于构建跨平台 GUI 应用程序的开源软件包 - Avalonia 发挥作用的地方。它提供了缺失的环节,使 .NET UI 功能也实现了跨平台。

Avalonia 是 WPF 的精神继承者,但比 WPF 更强大,可用于

  • 可在Windows、Mac和Linux上运行的桌面解决方案
  • 在浏览器中运行的Web应用程序(通过WebAssembly)
  • 适用于Android、iOS和Tizen的移动应用程序。

我称 Avalonia 为 Multiplatform WPF++。

我过去写了很多关于 Avalonia 的文章,特别是,我在 《使用 AvaloniaUI 进行跨平台 UI 编码的简单示例》 中解释了为什么 Avalonia 在创建跨平台 UI 应用程序方面远优于 Xamarin、MAUI、Node.js 或 UNO Platform。

当您创建一个需要在 Linux 上运行的应用程序时,它也必须在 Linux 上进行测试,有时甚至需要调试,因为在应该在多个平台上运行的代码中可能存在特定于 Linux 的代码,甚至特定于 Linux 的 bug。

对于 Windows 开发人员(以及大多数使用 .NET 开发的开发人员 - 在 Windows 上开发),Windows Subsystem for Linux (WSL) 非常方便,它允许在开发代码的同一台 Windows 计算机上运行 Linux .NET 应用程序,甚至可以使用 Visual Studio 2022 进行调试。

本文介绍如何使用 Visual Studio 2022 在 Windows 10 上运行和调试 Linux .NET 代码应用程序。

Windows 和 Visual Studio 版本

在我的测试中,我使用了 Windows 11 和 Visual Studio 2022。

我不确定 Visual Studio 的前一个版本(VS2019)是否也允许调试 .NET Linux 应用程序,但即使允许,可能也需要克服更多难题,所以我建议使用 VS2022。我在此过程中的体验几乎没有遇到任何麻烦。

在 Windows 10 和 11 上安装 WSL2

我不会列出在 Windows 10 和 11 操作系统上安装 WSL2(WSL 的高级版本)所需的所有步骤。有很多网站对此进行了详细介绍,例如 《如何在 Windows 10 上安装 WSL 2》《如何在 Windows 10 和 Windows 11 上安装 Linux WSL2》

我了解到在 Windows 11 上安装 WSL2 比在 Windows 10 上安装要容易得多。

安装用于 WSL 调试的 Visual Studio 2022 组件

有一个 Visual Studio 组件需要安装(或验证已安装)。

在 Visual Studio 中,打开 **工具** 菜单,然后选择 **获取工具和功能...** 菜单项。

在打开的组件安装窗口中,选择 **Individual Components**(单独组件)选项卡,然后在搜索框中输入 **WSL**。

应该会显示 **.NET Debugging with WSL**(使用 WSL 进行 .NET 调试)组件。安装该组件(如果尚未安装)。

运行 WSL Linux Shell(在 Visual Studio 之外)

要从 Windows 命令提示符启动 Linux shell,请使用以下命令:

wsl --install -d Ubuntu  

如果您是第一次执行此操作,系统可能会要求您设置用户名和密码;然后 Linux shell 将打开。

在 Linux shell 中,您可以尝试您喜欢的 UNIX 命令,例如 `ls`、`cat` 或 `grep`。

您可以通过在 Windows 命令提示符或 Explorer 中转到“\\wsl$\Ubuntu\home\<linux-acct-name>”来访问您的 Linux 主目录。这可能需要,例如,在您的 Windows OS 和 Linux 之间复制某些文件或文件夹。

您可以像在真正的 Linux 机器上一样安装您喜欢的 Linux 程序,例如,通过输入

sudo apt install emacs

在 Linux shell 中。

从 Linux Shell 运行 UI 程序

在这里,我将演示如何从 WSL Linux shell 运行任何 Linux UI 程序(不一定是 .NET 程序)。

在 Windows 10 或 11 上,您需要从 sourceforge.net/projects/vcxsrv/ 下载、安装并运行 VcXsvr 应用程序。

安装后,您的桌面上会出现 XLaunch 图标。

为了运行 VcXsrv,您必须单击此图标,然后按照以下步骤操作:

  • 在第一个屏幕上选择 **Multiple Windows**(多个窗口)选项(默认),然后按 **Next**(下一步)按钮。

  • 在第二个屏幕上选择 **Start no client**(不启动客户端)选项(默认),然后按 **Next**(下一步)按钮。

  • 在第三个屏幕上,将 **Disable access control**(禁用访问控制)选项添加到默认选项中,然后按 **Next**(下一步)。

  • 在第四个屏幕上按 **Finish**(完成)按钮。

现在,尝试在 Linux shell 中运行一个启动 Linux UI 应用程序的命令,例如:

xterm  

这将导致以下错误:

xterm: Xt error: Can't open display:
xterm: DISPLAY is not set  

我们需要将您的 Linux 系统上的 `DISPLAY` 变量设置为包含 `<your-windows-ip-address>:0.0`。在 WSL Linux shell 中(至少对于 Ubuntu 20.04)为您执行此操作的魔法行是:

export DISPLAY=$(route.exe print | grep 0.0.0.0 | head -1 | awk '{print $4}'):0.0  

运行此行后,尝试

echo $DISPLAY  

查看您的 `DISPLAY` 变量被设置为多少。在我的情况下,它是:

10.0.0.7:0.0  

还建议您运行

export LIBGL_ALWAYS_INDIRECT=1  

以避免出现一些错误消息。

现在再次运行 `xterm` 命令,瞧,您的功能齐全的 `xterm` 将作为窗口之一从 Linux shell 中弹出。

作为 xterm 的替代品,您也可以尝试 xclock - Linux 时钟窗口应该会弹出。

使用 Visual Studio 2022 调试 WSL 上的 .NET 项目

代码位置

视觉和非视觉项目都属于 NP.Ava.Demos 仓库。您可以使用 Github 的“下载为 zip”选项下载整个仓库,或者使用 git 的 `clone` 命令克隆仓库。

git clone https://github.com/npolyak/NP.Ava.Demos.git  

本文的两个项目是:

  1. `ConsoleAppForLinuxSubsystemDebuggingDemo` - 一个简单的非视觉 Linux 应用程序示例。
  2. `AvaloniaAppForLinuxSubsystemDebuggingDemo` - 一个简单的 Linux 可视应用程序示例。

调试控制台(非视觉)Linux 应用程序

打开仓库中 `ConsoleAppForLinuxSubsystemDebuggingDemo` 文件夹下的 `ConsoleAppForLinuxSubsystemDebuggingDemo.sln` 解决方案。

Program.cs 文件中的代码目的是打印有关运行程序的操作系统的一些信息。

bool isLinux = OperatingSystem.IsLinux();

if (isLinux)
{
    Console.WriteLine("Yes, it is Linux!!!");
}
else
{
    Console.WriteLine("No, it is not Linux");
}

if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
    Console.WriteLine("Yes, indeed Linux!!!");
}

Console.WriteLine($"RuntimeInformation.OSDescription = 
                   '{RuntimeInformation.OSDescription}'");

// gives Linux type, version number and architecture:
Console.WriteLine($"RuntimeInformation.RuntimeIdentifier = 
                   '{RuntimeInformation.RuntimeIdentifier}'");

Console.WriteLine($"Environment.OSVersion = '{Environment.OSVersion}'");  

您可以通过在代码中设置断点后,按 **Debug**(调试)按钮在 Windows 上进行调试。

在 Windows 10 上运行程序,程序将产生以下输出:

No, it is not Linux
RuntimeInformation.OSDescription = 'Microsoft Windows 10.0.19044'
RuntimeInformation.RuntimeIdentifier = 'win10-x64'
Environment.OSVersion = 'Microsoft Windows NT 10.0.19044.0'  

注意,**Debug** 按钮(上图中红色椭圆形内的按钮)右侧有一个向下的箭头。如果您按下该箭头,您将看到一个菜单弹出,其中包含 WSL 选项。

单击 **WSL** 选项,然后再次按 **Debug**(调试)按钮。

它将在相同的断点处停止,但现在,应用程序将作为 Linux 程序在 WSL 上运行。此程序的输出将是:

Yes, it is Linux!!!
Yes, indeed Linux!!!
RuntimeInformation.OSDescription = 
   'Linux 5.10.60.1-microsoft-standard-WSL2 #1 SMP Wed Aug 25 23:20:18 UTC 2021'
RuntimeInformation.RuntimeIdentifier = 'ubuntu.20.04-x64'
Environment.OSVersion = 'Unix 5.10.60.1'  

重要提示:在 WSL 上运行的 Linux 程序的输出将写入 **Visual Studio 输出窗口**,而不是像 Windows 程序那样写入打开的控制台窗口。

调试 Avalonia GUI .NET Linux 应用程序

现在打开位于 NP.Avalonia.Demos 仓库的同名文件夹下的 `AvaloniaAppForLinuxSubsystemDebuggingDemo.sln` 解决方案。

由于我们现在要调试一个 UI 应用程序,请不要忘记按照上述方法(除非已启动)在 Windows 10 上启动您的 **VcXsrv**。

这个非常简单的 UI 应用程序的非标准代码位于 `MainWindow.axaml` 和 `MainWindow.axaml.cs` 文件中。

这是 MainWindow.axaml 文件的内容

<Window xmlns="https://github.com/avaloniaui"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        x:Class="AvaloniaAppForLinuxSubsystemDebuggingDemo.MainWindow"
        Title="AvaloniaAppForLinuxSubsystemDebuggingDemo"
        Width="500"
        Height="300">
	<Button x:Name="TestDebuggingButton"
			Content="Test Debugging"
			HorizontalAlignment="Center"
			VerticalAlignment="Center" />
</Window>  

它在窗口中央定义了一个名为“TestDebuggingButton”的单按钮。

MainWindow.axaml.cs 文件内容同样简单。它定义并为按钮的 `Click` 事件添加了一个处理程序:

using Avalonia.Controls;
using Avalonia.Interactivity;

namespace AvaloniaAppForLinuxSubsystemDebuggingDemo
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            TestDebuggingButton.Click += TestDebuggingButton_Click;
        }

        private void TestDebuggingButton_Click(object? sender, RoutedEventArgs e)
        {
           
        }
    }
}

在 `TextDebugginButton_Click(...)` 处理程序方法中设置一个断点。

现在将 **Debug**(调试)按钮切换到 WSL(方式与上一小节相同)。请注意,该项目现在有一个包含 `launchSettings.json` 文件的 *Properties* 子文件夹。

在这种情况下 - 此文件已提交到 git 仓库,但当您创建新项目时,当您将 **Debug**(调试)按钮切换到 **WSL** 时,将创建并添加到项目中的此文件。

单击 `launchSettings.json` 文件将其打开。这是其内容:

{
  "profiles": {
    "AvaloniaAppForLinuxSubsystemDebuggingDemo": {
      "commandName": "Project"
    },
    "WSL": {
      "commandName": "WSL2",
      "environmentVariables": {
        "DISPLAY": "10.0.0.7:0.0",
        "LIBGL_ALWAYS_INDIRECT": "1"
      },
      "distributionName": ""
    }
  }
}  

您需要将 **DISPLAY** 设置更改为您拥有的任何值。为了确定 `DISPLAY` 变量需要设置为多少,您可以使用上面“从 Linux Shell 运行 UI 程序”部分中描述的相同方法,即:

  1. 通过运行以下命令打开 Linux shell:
    wsl --install -d Ubuntu     
    在 Windows 命令提示符中。
  2. 在 Linux shell 中,运行以下命令:

    echo $(route.exe print | grep 0.0.0.0 | head -1 | awk '{print $4}'):0.0 
    此命令的输出将产生您需要在 `launchSettings.json` 文件中为 `DISPLAY` 变量分配的值(在我的情况下是“10.0.0.7:0.0”)。

现在您已准备好调试程序。

按 **Debug**(调试)按钮启动程序。

一个窗口弹出,在其左上角显示 **X** term 图标。

这就是我们的 Avalonia 应用程序在 WSL 上运行。

按下窗口中央的按钮,您将在 `TestDebuggingButton_Click(...)` 方法体内的断点处停止。

结论

本文详细介绍了如何使用 WSL 和 Visual Studio 2022 测试和调试 .NET/Avalonia Linux 应用程序。

历史

  • 2022 年 4 月 24 日:初始版本。
  • 2023 年 12 月 26 日 - 升级到 Avalonia 11。
© . All rights reserved.