ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

如何在 Windows 原生应用中用 C/WinRT 投影调用 WSL Container API 执行 Linux 命令?

如何在 Windows 原生应用中用 C/WinRT 投影调用 WSL Container API 执行 Linux 命令? 如何在 Windows 原生应用中用 C#/WinRT 投影调用 WSL Container API 执行 Linux 命令【免费下载链接】WSLWindows Subsystem for Linux项目地址: https://gitcode.com/GitHub_Trending/ws/WSL如果你的目标是从一个 Windows 原生可执行文件里启动 WSL 容器、在其中运行一条 Linux 命令并拿到输出WSL 仓库中的Microsoft.WSL.ContainersSDK 提供了一条现成路径通过 C#/WinRT 投影引用wslcsdkcs.dll在Microsoft.WSL.Containers命名空间下用普通 C# 代码完成建会话 → 拉镜像 → 建容器 → 跑命令 → 回收退出码 → 清理的完整生命周期。仓库里提供了可直接构建的 C# 示例 WSLC-NextCloud.NET 8以及 C# API 端到端示例 和完整的 C# API 参考。适用环境为 Windows x64/ARM64、.NET 8SDK 目前处于 preview 阶段接口可能在不通知的情况下变更不建议直接用于生产工作负载。准备条件按 SDK NuGet 包说明 列出的前置条件准备WSL 运行时使用wsl --install --no-distribution安装它会同时提供wslcCLI.NET 8 SDKC#/WinRT 投影面向 .NET 8 的 MSBuild 项目NuGet 包在项目中引用Microsoft.WSL.Containers包。引用后wslcsdkcs.dll投影程序集会被 MSBuild 自动加入引用代码侧只需using Microsoft.WSL.Containers;会话开始前可以先用WslcService检查环境。Service 类文档 给出的用法IReadOnlyListComponent missing WslcService.GetMissingComponents(); if (missing.Count 0) { Console.WriteLine(All required components are installed.); } else { Console.WriteLine($Missing: {string.Join(, , missing)}); }组件缺失时文档给出了两种处理方式命令行执行wsl --install或在代码中调用WslcService.InstallWithDependencies()也可用带进度回调的InstallWithDependenciesAsync()。确认环境后可以用WslcService.GetVersion()打印当前 WSL 版本Major.Minor.Revision三段。主路径一条命令跑完的 C# 程序下面的完整程序来自仓库的 端到端示例它执行alpine:latest镜像里的/bin/echo Hello from WSL Container!是文档中与执行一条 Linux 命令最直接对应的最短路径using Microsoft.WSL.Containers; using System; using System.Text; using System.Threading.Tasks; class Program { static async Taskint Main() { // 0. Check prerequisites var missing WslcService.GetMissingComponents(); if (missing.Count 0) { Console.WriteLine(WSL components are missing. Run: wsl --install); return 1; } var ver WslcService.GetVersion(); Console.WriteLine($WSL version: {ver.Major}.{ver.Minor}.{ver.Revision}); // 1. Create a session var sessionSettings new SessionSettings(MyApp, C:\WslcData) { CpuCount 4, MemorySizeInMB 4096 }; var session new Session(sessionSettings); session.Start(); // 2. Pull an image var pullOp session.PullImageAsync(new PullImageOptions(docker.io/library/alpine:latest)); pullOp.Progress (op, progress) Console.WriteLine($Pull: {progress.Status} {progress.CurrentBytes}/{progress.TotalBytes}); await pullOp; // 3. Configure an init process var initProcSettings new ProcessSettings { CommandLine new[] { /bin/echo, Hello from WSL Container! }, OutputMode ProcessOutputMode.Event }; // 4. Configure and create a container var containerSettings new ContainerSettings(alpine:latest) { Name hello-container, InitProcess initProcSettings }; var container session.CreateContainer(containerSettings); // 5. Subscribe to init process events before starting var exited new TaskCompletionSourceint(TaskCreationOptions.RunContinuationsAsynchronously); container.InitProcess.OutputReceived data Console.Write(Encoding.UTF8.GetString(data)); container.InitProcess.Exited code exited.TrySetResult(code); // 6. Start the container container.Start(); // 7. Wait for the init process to exit (30-second timeout) var completed await Task.WhenAny(exited.Task, Task.Delay(TimeSpan.FromSeconds(30))); int exitCode completed exited.Task ? exited.Task.Result : -1; Console.WriteLine($Process exited with code: {exitCode}); // 8. Clean up if (container.State ContainerState.Running) { container.Stop(Signal.SIGTERM, TimeSpan.FromSeconds(10)); } container.Delete(DeleteContainerOption.None); session.Terminate(); return exitCode; } }文档对每一步的说明结合 Session 参考 与 Process 参考检查前置条件GetMissingComponents()非空时按提示运行wsl --install程序直接返回失败创建会话SessionSettings接收会话名和会话存储目录示例中为MyApp/C:\WslcDataCpuCount 4、MemorySizeInMB 4096指定 VM 资源session.Start()启动会话 VM 并注册内部终止等待拉取镜像PullImageAsync可 awaitProgress回调报告Status与CurrentBytes/TotalBytes同步版本PullImage也可用配置 init 进程ProcessSettings.CommandLine用字符串数组表达命令行OutputMode ProcessOutputMode.Event是OutputReceived/ErrorReceived事件生效的前提Stream模式则改用GetOutputStream(...)读 WinRT 流创建容器ContainerSettings(alpine:latest)第一参数是镜像Name是容器名InitProcess指定容器启动时运行的命令订阅事件后再container.Start()init 进程由Container.Start()启动而不是对InitProcess单独调Start()等待退出用TaskCompletionSourceint承接Exited事件配合 30 秒超时兜底清理容器仍在运行则Stop(SIGTERM, 10 秒)随后Delete容器、Terminate会话。执行后OutputReceived会把容器内 echo 的输出原样写到控制台Exited携带进程退出码程序本身把该退出码作为Main的返回值。变体在长驻容器里执行任意命令如果命令不是跑完即走而是要在一个持续存活的容器里执行并取回输出例如转发 CLI 参数、长时间服务仓库中的 WSLC-NextCloud 示例 展示了标准做法init 进程用sleep保活容器真正要执行的 Linux 命令通过Container.CreateProcess(...)作为二级进程启动。关键片段来自该示例// The init process keeps the container alive while we exec the entrypoint. var initProcess new ProcessSettings { CommandLine new Liststring { /bin/sleep, infinity }, }; var containerSettings new ContainerSettings(imageName) { InitProcess initProcess, EnableAutoRemove true, }; using var container session.CreateContainer(containerSettings); container.Start(); // Exec the actual command inside the running container var processSettings new ProcessSettings { CommandLine new Liststring { /entrypoint.sh, apache2-foreground }, OutputMode ProcessOutputMode.Event, }; using var process container.CreateProcess(processSettings); process.OutputReceived data Write(stdout, data); process.ErrorReceived data Write(stderr, data); process.Exited code { exitCode code; stopEvent.Set(); }; process.Start();与主路径的区别init 进程只做保活CreateProcessprocess.Start()才是执行命令的动作Process 参考 明确Start()只用于CreateProcess创建的二级进程。二级进程可以拿到Pid、State退出后ExitCode有效stdin 也可以写——GetInputStream()返回 WinRT 输出流用DataWriter写入后FlushAsync()。C/WinRT 投影下有结构等价的 WSLC-Neofetch 示例它把可执行文件的所有命令行参数转发给容器内的neofetch构建方式见 其 READMEnuget restore WSLCNeofetch.sln后用msbuild WSLCNeofetch.sln /p:ConfigurationDebug /p:Platformx64。C# 侧等价的最小可运行样本是 NextClouddotnet build -c Debug构建dotnet run -c Debug运行。运行与验证仓库自带的 C# 样本 WSLC-NextCloud 是最方便的端到端验证对象dotnet build -c Debug # 构建要求 .NET 8 SDK dotnet run -c Debug # 运行运行后的验证方式是文档明确给出的打开http://localhost:8080宿主 8080 端口映射到容器 80 端口确认服务已启动然后在终端按Enter停止服务并清理容器。首次运行会拉取约 1.5 GB 的镜像README 提示可能需要几分钟。对于自己写的程序验证手段与主路径一致OutputReceived事件是否收到容器内命令的输出、Exited事件/ExitCode是否为预期的退出码、GetMissingComponents()是否返回空列表。NextCloud 示例还说明了存储布局的一个实际约束来自 Program.cs 注释会话存储目录必须为空才能创建会话——SDK 会在其中创建并复用自己的 VHD所以持久化数据要放在同级独立目录里并单独 bind mount。该示例在会话旁建了两个目录WslcNextcloudStorage\临时 VHD和WslcNextcloudData\挂载到容器/var/www/html/data。已知限制preview 状态SDK 处于 preview未来版本可能无通知地破坏 API 稳定性生产工作负载不要依赖其稳定性平台仅支持 x64 和 ARM64投影缺口known-gaps 文档 列出了 C# 投影不提供、需要用事件或 WinRT 流替代的 C API 能力包括原始句柄WslcGetProcessExitEvent等改用Exited/OutputReceived事件、WslcProcessCallbacks已包装为事件以及Container.StartFlags不直接暴露Container.Start()在 init 进程使用ProcessOutputMode.Event或Stream时自动设置ATTACH输出模式约束OutputReceived/ErrorReceived要求OutputMode.EventGetOutputStream(...)要求OutputMode.StreamExited在两种模式下都可用。如果你接下来要在构建阶段一并生成容器镜像NuGet 包文档还说明了WslcImageMSBuild 项与 CMake 的wslc_add_image集成详见 包说明C# 侧其余 API端口映射、Volume、镜像导入导出等在 C# API 参考 中按数据类、设置类和核心类分章列出。【免费下载链接】WSLWindows Subsystem for Linux项目地址: https://gitcode.com/GitHub_Trending/ws/WSL创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表