尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

WSL Container API 开发者参考:在 Windows 应用中用 C / C / C++ 驱动 Linux 容器

WSL Container API 开发者参考:在 Windows 应用中用 C / C / C++ 驱动 Linux 容器 WSL Container API 开发者参考在 Windows 应用中用 C / C# / C 驱动 Linux 容器【免费下载链接】WSLWindows Subsystem for Linux项目地址: https://gitcode.com/GitHub_Trending/ws/WSLWSL Container API 是 WSLWindows Subsystem for Linux向 Windows 桌面开发者开放的一套容器编程接口允许你把 Linux 容器作为应用逻辑的一部分来创建、启动和销毁。本文以仓库中的 API 参考文档入口 为骨架系统梳理 C、C#、C 三种语言投影的能力分层Session → Container → Process、C API 的结构体与错误码体系并给出完整的端到端生命周期示例与源码级印证读完本文你将能够判断该 API 是否适合你的应用场景并能立刻搭建出第一个由 Windows 代码驱动的 Linux 容器。状态提示根据官方参考文档WSL Container API 当前仍处于preview预览阶段未来版本可能引入破坏性变更breaking changes并计划在2026 年秋季fall 2026达到正式可用GA。建议现阶段仅用于可行性评估待 GA 后再部署生产级代码。一、定位Linux 容器如何成为 Windows 应用的组成部分传统上WSL 以发行版distribution为单位供用户交互式使用而 WSL Container API 提供的是另一条路径让 Windows 应用开发者以编程方式使用 Linux 容器把容器当作应用内部的执行单元。它面向的是 Windows 应用本身例如服务端组件、计算引擎、沙箱化辅助进程与通过wsl.exe/wslc.exe命令行交互的用法互为补充——命令行工具提供交互式能力而本文所述的 SDK API 则嵌入应用逻辑。整个 API 的能力被组织成一条清晰的分层模型Session会话 → Container容器 → Process进程Session一次资源生命周期。它负责分配 CPU、内存、VHD 存储等资源相当于一个隔离的容器运行时实例Container建立在 Session 之上的容器实体。每个容器有一个 init process初始进程Process容器内运行的进程可创建第二个、第三个进程并订阅其输出与退出事件。三种语言的投影描述的是同一套底层能力只是表面 API 不同。原文中的语言投影概览如下语言命名空间 / 头文件参考文档Cwslcsdk.hwslcsdk.lib/wslcsdk.dllC API referenceC#Microsoft.WSL.ContainersC# API referenceCMicrosoft::WSL::ContainersC API reference其中 C 是平铺的 C 风格函数 APISTDAPI导出C# 是 WinRT 投影由wslcsdk.idl生成C 是 C/WinRT 投影头文件#include winrt/Microsoft.WSL.Containers.h命名空间winrt::Microsoft::WSL::Containers错误以winrt::hresult_error形式抛出镜像与安装类操作返回IAsyncActionWithProgressT。二、C API 全景从头文件到功能分组C API 是整套 SDK 的基础形态头部与库信息如下见 C 参考文档Headerwslcsdk.hLibrarywslcsdk.lib/wslcsdk.dll在仓库中该头文件的完整定义位于 src/windows/WslcSDK/wslcsdk.h导出实现位于 src/windows/WslcSDK/wslcsdk.cpp 与 src/windows/WslcSDK/wslcsdk.def。头文件采用不透明结构体opaque struct设计所有设置结构体对调用方隐藏内部布局只暴露固定大小的字节缓冲配合WslcInit*初始化与WslcSet*设置函数使用。从源码可见// Session values #define WSLC_SESSION_OPTIONS_SIZE 72 typedef struct WslcSessionSettings { __declspec(align(8)) BYTE _opaque[72]; } WslcSessionSettings; DECLARE_HANDLE(WslcSession);同理还有 104 字节的WslcContainerSettings、72 字节的WslcProcessSettings以及WslcSession、WslcContainer、WslcProcess等句柄类型。这种设计保证 ABI 稳定代价是调用方必须严格遵循先 Init 再 Set 再 Create的使用契约。2.1 结构体StructuresC API 提供以下结构体详见 structures/index.md句柄与常量Handle Types、Constants三件套设置WslcSessionSettings、WslcContainerSettings、WslcProcessSettings存储与网络WslcVhdRequirements、WslcContainerPortMapping、WslcContainerVolume、WslcContainerNamedVolume回调与进度WslcProcessCallbacks、WslcImageProgressDetail、WslcImageProgressMessage镜像操作选项WslcPullImageOptions、WslcImportImageOptions、WslcLoadImageOptions、WslcImageInfo、WslcTagImageOptions、WslcPushImageOptions版本与崩溃信息WslcVersion、WslcSessionCrashDumpInfo2.2 功能 API 分组C API 的导出函数被组织为七大功能区每区均有独立索引文档功能区能力索引文档Session APIs创建/终止会话、配置 CPU/内存/超时/VHD、订阅终止事件与会话崩溃转储回调session-apis/index.mdContainer APIs创建/启动/停止/删除容器、检查容器状态、配置主机名/域名/网络模式/端口映射/卷container-apis/index.mdProcess APIs配置与创建进程、获取 PID/退出码/退出事件/IO 句柄、发送信号process-apis/index.mdImage APIs拉取/推送/导入/加载/删除/打标签镜像image-apis/index.mdStorage APIs创建/删除会话的 VHD 卷storage-apis/index.mdInstall and Version APIs检查缺失组件、安装依赖、获取 SDK 版本install-and-version-apis/index.mdCallback Types镜像进度、安装进度、进程退出、崩溃转储、stdio 等回调签名callback-types/index.md配套还有完整的 Enumerations如WslcContainerState、WslcSignal、WslcPortProtocol、WslcContainerNetworkingMode、WslcComponentFlags、WslcProcessState、WslcSessionFeatureFlags等。部分 API 尚未实现见 not-yet-implemented-apis.md。2.3 错误码体系Error CodesC API 的错误以HRESULT返回错误码定义在 error-codes.md源码同款宏定义见 src/windows/WslcSDK/wslcsdk.h。完整的错误码表如下SymbolHex ValueWSLC_E_BASE0x0600WSLC_E_IMAGE_NOT_FOUND0x80040601WSLC_E_CONTAINER_PREFIX_AMBIGUOUS0x80040602WSLC_E_CONTAINER_NOT_FOUND0x80040603WSLC_E_VOLUME_NOT_FOUND0x80040604WSLC_E_CONTAINER_NOT_RUNNING0x80040605WSLC_E_CONTAINER_IS_RUNNING0x80040606WSLC_E_SESSION_RESERVED0x80040607WSLC_E_INVALID_SESSION_NAME0x80040608WSLC_E_NETWORK_NOT_FOUND0x80040609WSLC_E_WU_SEARCH_FAILED0x8004060AWSLC_E_SDK_UPDATE_NEEDED0x8004060BWSLC_E_CONTAINER_DISABLED0x8004060CWSLC_E_REGISTRY_BLOCKED_BY_POLICY0x8004060DWSLC_E_VOLUME_NOT_AVAILABLE0x8004060EWSLC_E_SESSION_NOT_FOUND0x8004060FWSLC_E_VM_NOT_RUNNING0x80040610WSLC_E_EVENTS_LOST0x80040611WSLC_E_EVENT_STREAM_FINISHED0x80040612WSLC_E_CONTAINER_DELETED0x80040613注意WSLC_E_EVENTS_LOST/WSLC_E_EVENT_STREAM_FINISHED与 C#/C 投影中的ProcessOutputMode.Event事件式输出模式直接相关当事件流因缓冲等原因丢失或被消费完毕时会以这些错误码呈现。头文件中还注明确保wslc.idl与wslcsdk.idl同步更新说明 C 错误码与 WinRT 投影错误码是同一套体系。三、C# 与 C 投影面向托管与原生现代开发3.1 C#Microsoft.WSL.ContainersC# 投影的完整结构见 C# 参考索引包含 Overview、Projected Namespace、Common CsWinRT Type Mappings 等文档。公共 C# 表面直接镜像 WinRT 表面由winrt_*.h/winrt_*.cpp包装器实现。核心类型包括Service 类WslcService检查缺失组件、版本查询、安装依赖Core 类Session、Container、ProcessSettings 类SessionSettings、ContainerSettings、ProcessSettings、PullImageOptions、PushImageOptions、TagImageOptions、VhdOptionsData 类ImageInfo、ImageProgress、InstallProgress、ProcessCrashInformation、ServiceVersion、VhdOwner、ContainerVolume、ContainerNamedVolume、ContainerPortMappingDelegates and Eventsdelegates-and-events.mdEnumerationsComponent、ContainerNetworkingMode、ContainerState、DeleteContainerOption、Error、ImageProgressStatus、PortProtocol、ProcessOutputHandle、ProcessOutputMode、ProcessState、SessionTerminationReason、Signal、VhdType已知差异见 known-gaps.md。仓库中的 WinRT 定义来源为 src/windows/WslcSDK/winrt/wslcsdk.idl其中可以看到Session、SessionSettings、ContainerPortMapping、ProcessCrashInformation、AuthenticateResult等 runtimeclass 的真实定义例如SessionSettings具有Name、StoragePath、CpuCount、MemorySizeInMB、Timeout、VhdRequirements、EnableGpu属性ContainerNetworkingMode枚举为None 0/Bridged 1。3.2 Cwinrt::Microsoft::WSL::ContainersC 采用 C/WinRT 投影见 C 参考索引Header#include winrt/Microsoft.WSL.Containers.hNamespacewinrt::Microsoft::WSL::Containers错误以winrt::hresult_error抛出镜像与安装操作返回IAsyncActionWithProgressT事件委托见 delegates-and-events/index.mdProcessCrashHandler、ProcessExitHandler、ProcessOutputHandler、SessionTerminationHandler未实现项与已知差异见 not-yet-implemented-and-known-gaps.md典型调用形态与 C# 一一对应auto missing WslcService::GetMissingComponents(); // Component 位标志 SessionSettings sessionSettings{ LMyApp, LC:\\WslcData }; sessionSettings.CpuCount(4); sessionSettings.MemorySizeInMB(4096); Session session{ sessionSettings }; session.Start(); auto pullOp session.PullImageAsync(PullImageOptions{ Ldocker.io/library/alpine:latest }); co_await pullOp; // 异步进度操作四、端到端示例完整的容器生命周期以下生命周期覆盖了 API 的核心流程C 完整示例见 end-to-end-example.md检查前提组件缺失则提示wsl --install打印 SDK 版本初始化会话设置并创建会话拉取镜像docker.io/library/alpine:latest配置 init process/bin/echo Hello from WSL Container!配置并创建容器启动容器等待 init process 退出并读取退出码停止并删除容器终止会话、释放句柄4.1 C 完整示例#include winsock2.h #include windows.h #include stdio.h #include objbase.h #include filesystem #include wslcsdk.h #pragma comment(lib, ole32.lib) #pragma comment(lib, wslcsdk.lib) int main() { // Initialize COM CoInitializeEx(nullptr, COINIT_MULTITHREADED); HRESULT hr; PWSTR error nullptr; // 0. Check prerequisites WslcComponentFlags missing WSLC_COMPONENT_FLAG_NONE; hr WslcGetMissingComponents(missing); if (FAILED(hr) || missing ! WSLC_COMPONENT_FLAG_NONE) { printf(WSL components are missing. Run: wsl --install\n); CoUninitialize(); return 1; } WslcVersion ver {}; WslcGetVersion(ver); printf(WSL version: %u.%u.%u\n, ver.major, ver.minor, ver.revision); // 1. Initialize and create a session std::filesystem::path storagePath std::filesystem::current_path(); WslcSessionSettings sessionSettings; hr WslcInitSessionSettings(LMyApp, storagePath.c_str(), sessionSettings); if (FAILED(hr)) return 1; // Optionally customize resources WslcSetSessionSettingsCpuCount(sessionSettings, 4); WslcSetSessionSettingsMemory(sessionSettings, 4096); WslcSession session nullptr; hr WslcCreateSession(sessionSettings, session, error); if (FAILED(hr)) { wprintf(LSession creation failed: %s\n, error ? error : Lunknown); CoTaskMemFree(error); CoUninitialize(); return 1; } // 2. Pull an image WslcPullImageOptions pullOpts {}; pullOpts.uri docker.io/library/alpine:latest; hr WslcPullSessionImage(session, pullOpts, error); if (FAILED(hr)) { wprintf(LPull failed: %s\n, error ? error : Lunknown); CoTaskMemFree(error); WslcTerminateSession(session); WslcReleaseSession(session); CoUninitialize(); return 1; } // 3. Configure an init process WslcProcessSettings initProcSettings; WslcInitProcessSettings(initProcSettings); PCSTR argv[] { /bin/echo, Hello from WSL Container! }; WslcSetProcessSettingsCmdLine(initProcSettings, argv, 2); // 4. Configure and create a container WslcContainerSettings containerSettings; WslcInitContainerSettings(alpine:latest, containerSettings); WslcSetContainerSettingsName(containerSettings, hello-container); WslcSetContainerSettingsInitProcess(containerSettings, initProcSettings); WslcContainer container nullptr; hr WslcCreateContainer(session, containerSettings, container, error); if (FAILED(hr)) { wprintf(LContainer creation failed: %s\n, error ? error : Lunknown); CoTaskMemFree(error); WslcTerminateSession(session); WslcReleaseSession(session); CoUninitialize(); return 1; } // 5. Start the container hr WslcStartContainer(container, WSLC_CONTAINER_START_FLAG_NONE, error); if (FAILED(hr)) { wprintf(LStart failed: %s\n, error ? error : Lunknown); CoTaskMemFree(error); WslcDeleteContainer(container, WSLC_DELETE_CONTAINER_FLAG_FORCE, nullptr); WslcReleaseContainer(container); WslcTerminateSession(session); WslcReleaseSession(session); CoUninitialize(); return 1; } // 6. Wait for the init process to exit WslcProcess initProc nullptr; hr WslcGetContainerInitProcess(container, initProc); if (SUCCEEDED(hr)) { HANDLE exitEvent nullptr; if (SUCCEEDED(WslcGetProcessExitEvent(initProc, exitEvent))) { WaitForSingleObject(exitEvent, 30000); // 30-second timeout } INT32 exitCode 0; if (SUCCEEDED(WslcGetProcessExitCode(initProc, exitCode))) { printf(Process exited with code: %d\n, exitCode); } WslcReleaseProcess(initProc); } // 7. Clean up WslcContainerState containerState WSLC_CONTAINER_STATE_INVALID; if (SUCCEEDED(WslcGetContainerState(container, containerState)) containerState WSLC_CONTAINER_STATE_RUNNING) { WslcStopContainer(container, WSLC_SIGNAL_SIGTERM, 10, nullptr); } WslcDeleteContainer(container, WSLC_DELETE_CONTAINER_FLAG_NONE, nullptr); WslcReleaseContainer(container); WslcTerminateSession(session); WslcReleaseSession(session); CoUninitialize(); return 0; }从源码结构看WslcInit*系列是创建前必须调用的初始化函数WslcCreate*之前的所有设置必须通过WslcSet*完成因为设置结构体是不透明的见 src/windows/WslcSDK/wslcsdk.h。句柄WslcSession、WslcContainer、WslcProcess遵循显式的Release语义会话结束时调用WslcTerminateSession主动终止 VM 侧资源再WslcReleaseSession释放客户端句柄。4.2 C# 对照示例C# 版本见 C# end-to-end-example.md在流程上与 C 完全一致但改用异步 API 与事件订阅代码更简洁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; } }注意 C# 版本在启动前订阅InitProcess.OutputReceived/Exited事件配合ProcessOutputMode.Event事件式输出模式避免错过早期输出DeleteContainerOption枚举对应 C API 的WslcDeleteContainerFlags。4.3 C 对照示例C 版本见 C end-to-end-example.md与 C# 逻辑等价差异集中在 C/WinRT 语法以init_apartment()初始化 COM、用co_await消费IAsyncActionWithProgress、用single_threaded_vectorhstring()构造命令行参数、以 lambda 委托订阅OutputReceived/Exited事件并用WaitForSingleObject等待手动事件#include winrt/Microsoft.WSL.Containers.h #include winrt/Windows.Foundation.h #include winrt/Windows.Foundation.Collections.h using namespace winrt; using namespace winrt::Microsoft::WSL::Containers; using namespace winrt::Windows::Foundation; using namespace std::chrono_literals; int main() { init_apartment(); // 0. Check prerequisites auto missing WslcService::GetMissingComponents(); if (missing ! static_castComponent(0)) { printf(WSL components are missing. Run: wsl --install\n); return 1; } // 1. Create a session SessionSettings sessionSettings{ LMyApp, LC:\\WslcData }; sessionSettings.CpuCount(4); sessionSettings.MemorySizeInMB(4096); Session session{ sessionSettings }; session.Start(); // 2. Pull an image (异步进度操作) auto pullOp session.PullImageAsync(PullImageOptions{ Ldocker.io/library/alpine:latest }); co_await pullOp; // 3. Configure an init process ProcessSettings initProcSettings; initProcSettings.OutputMode(ProcessOutputMode::Event); auto argv single_threaded_vectorhstring(); argv.Append(L/bin/echo); argv.Append(LHello from WSL Container!); initProcSettings.CommandLine(argv); // 4. Configure and create a container ContainerSettings containerSettings{ Lalpine:latest }; containerSettings.Name(Lhello-container); containerSettings.InitProcess(initProcSettings); auto container session.CreateContainer(containerSettings); // 5. Subscribe to events, 6. Start, 7. Wait with 30s timeout, // 8. Stop/Delete/Terminate —— 与 C# 示例一一对应 // container.Start(); // initProcess.OutputReceived(...); initProcess.Exited(...); // WaitForSingleObject(exitedEvent.get(), 30000); // container.Stop(Signal::SIGTERM, 10s); // container.Delete(DeleteContainerOption::None); // session.Terminate(); return 0; }五、仓库中的配套资源示例、包与测试除 API 参考文档外仓库围绕 WSL Container API 提供了可直接运行的示例、NuGet 包与测试可作为进一步学习的参照C 示例最小化doc/samples/WSLC-HelloWorld —— 使用平铺 C APIwslcsdk.h的helloworld.c运行helloworld.exe即可从alpine:latest镜像启动轻量容器并执行echo构建方式为nuget restoremsbuildx64进度消息输出到 stderr见 README.md。C# 示例doc/samples/WSLC-CustomContainer/Program.cs、doc/samples/WSLC-NextCloud/Program.cs。C 示例doc/samples/WSLC-Neofetch/neofetch.cpp。NuGet 包C# 投影以Microsoft.WSL.Containers包分发包清单与使用说明见 nuget/Microsoft.WSL.Containersmanifests 与 docs/README.MD。WinRT 投影源码src/windows/WslcSDK/winrt/wslcsdk.idl 定义了 C#/C 投影的 runtimeclass、枚举与委托WslcsdkPrivate.cpp 等实现文件承载实际逻辑。测试test/windows/wslcwslc 测试套件、test/windows/WslcSdkTests.cpp、test/windows/WslcSdkWinRTTests.cpp可据此验证 API 的真实行为与边界条件。六、Preview 阶段的使用建议综合参考文档与源码接入该 API 时有几点值得注意API 尚未稳定wslcsdk.h顶部明确标注 PREVIEW NOTICE提示功能、函数签名与行为可能在预览期内变化src/windows/WslcSDK/wslcsdk.hC#/C 投影同样有 known gaps 与未实现 API 清单。生产项目应等待 GA 后再大规模依赖。先检查组件再初始化所有语言投影都提供GetMissingComponentsC 为WslcGetMissingComponents在创建会话前应先确认 WSL 组件齐全缺失时引导用户执行wsl --install。遵循资源契约C API 的设置结构体不透明必须按 Init → Set → Create 顺序使用句柄需要显式Release会话需要TerminateRelease双重清理。异步操作关注进度与取消拉取/推送/导入/加载镜像均为耗时操作C#/C 投影返回IAsyncActionWithProgressT可通过Progress回调C#或co_awaitC观察ImageProgressC API 则使用 callback-types 中的进度回调。事件式输出注意WSLC_E_EVENTS_LOSTProcessOutputMode.Event模式依赖事件流若缓冲丢失会收到0x80040611需要在应用层做好降级或重试策略。总体而言WSL Container API 将 Linux 容器的能力以 SDK 形式暴露给 Windows 应用开发者分层清晰Session → Container → Process三种语言投影能力等价、形态各异C 适合追求 ABI 稳定的原生集成C# 适合托管应用与异步事件编程C/WinRT 则面向现代原生开发。要深入某个具体函数或结构体可直接查阅 C API reference、C# API reference 与 C API reference 三个索引或直接阅读 wslcsdk.h 与 wslcsdk.idl 获得最准确的签名信息。【免费下载链接】WSLWindows Subsystem for Linux项目地址: https://gitcode.com/GitHub_Trending/ws/WSL创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表