
WSL 容器 SDK 数据类指南PullImageOptions 与 PushImageOptions 等引用数据类型的 C/WinRT 使用详解【免费下载链接】WSLWindows Subsystem for Linux项目地址: https://gitcode.com/GitHub_Trending/ws/WSLWSL 仓库Windows Subsystem for Linux中的Microsoft.WSL.ContainersSDKWSLC SDK提供了创建和管理运行在 WSL 内 Linux 容器的编程接口。本文聚焦于其 C/WinRT 投影中的一组引用数据类——PullImageOptions、PushImageOptions、TagImageOptions、VhdOptions与ServiceVersion逐项说明每个类的字段语义、与 C ABI 底层结构体的映射关系、构造与赋值时的校验规则并结合源码给出可直接编译运行的实战示例。读完本文你将能熟练使用这些选项类完成镜像拉取、推送、打标签、虚拟磁盘卷创建与版本查询等容器生命周期管理操作。引用的数据类把 C 结构体封装成 WinRT 对象在 WSLC SDK 的分层设计中SDK 对外暴露两套 API位于 wslcsdk.h 的纯 C ABIWslcPullSessionImage、WslcPushSessionImage等导出函数以及位于 src/windows/WslcSDK/winrt 的 WinRT 投影。C/WinRT 投影中有一类特殊的数据类Data Classes它们本身不执行任何容器操作而是作为参数载体把用户填写的配置URI、镜像名、标签、磁盘大小等打包成 WinRT 对象再在方法调用时翻译成 C ABI 要求的结构体。引用数据类Referenced data classes特指那些在Session与SessionSettings等核心类的 API 中被引用的选项/结果类型包括PullImageOptionsSession::PullImageAsync的参数PushImageOptionsSession::PushImageAsync的参数TagImageOptionsSession::TagImage的参数VhdOptionsSession::CreateVhdVolume与SessionSettings::VhdRequirements的参数ServiceVersionWslcService::GetVersion()的返回值从源码结构看这些类遵循完全一致的模式声明在头文件中如 PullImageOptions.h实现于同名.cpp如 PullImageOptions.cpp并通过DEFINE_TYPE_HELPERS宏接入 C/WinRT 的激活与get_strong/as机制。它们对应的 MIDL 定义统一声明在 wslcsdk.idl 中IDL 中声明的runtimeclass与 WinRT 元数据Microsoft.WSL.Containers.winmd是 C#/WinRT 等其他语言投影共享同一套 API 契约的基础。镜像拉取PullImageOptions字段语义与 C ABI 映射PullImageOptions封装了拉取镜像所需的全部信息。根据 wslcsdk.h 中WslcPullImageOptions结构体的定义其 C 形状为字段类型说明uriPCSTR镜像 URI例如docker.io/library/alpine:latest必填progressCallbackWslcContainerImageProgressCallback进度回调函数指针可选progressCallbackContextPVOID回调上下文指针可选registryAuthPCSTR注册表认证信息可选可空在 WinRT 投影中uri与registryAuth暴露为可读写的hstring属性而回调字段由框架在调用WslcPullSessionImage前自动填充开发者无需直接操作。WinRT 属性与 C 字段的对应关系如下Uri⇄WslcPullImageOptions::uriRegistryAuth⇄WslcPullImageOptions::registryAuth空字符串时置为nullptr进度回调 ⇄progressCallbackprogressCallbackContext构造与校验规则看 PullImageOptions.cpp 的实现有两个值得注意的约束URI 不可为空无论是构造函数还是Urisetter空字符串都会抛出hresult_invalid_argumentURI cannot be empty。选项一旦被使用即锁定ToStruct()首次调用时会把当前属性值固化到内部的WslcPullImageOptions结构体std::make_unique分配字段指向内部字符串此后任何 setter 再被调用都会抛出hresult_illegal_state_changeCannot change value after options have been applied。这意味着你应该先配置完所有属性再把对象传给 API。ToStruct()的字段填充逻辑PullImageOptions.cpp显示uri直接指向内部std::string的 C 字符串registryAuth在空串时被规范化为nullptrprogressCallback与progressCallbackContext初始置空由 Session.cpp 中的PullImageAsync在调用WslcPullSessionImage(ToHandle(), pullOptions, errorMessage.put())之前用内部的ImageProgressCallback与ProgressCallbackHelper上下文填充。使用示例// 构造选项URI 必填RegistryAuth 可选 PullImageOptions pullOptions{ Ldocker.io/library/alpine:latest }; // 可选的私有仓库认证来自 Session::Authenticate 的返回值 // pullOptions.RegistryAuth(Lbase64 X-Registry-Auth); // PullImageAsync 返回 IAsyncActionWithProgressImageProgress auto pull session.PullImageAsync(pullOptions); pull.Progress([](auto, ImageProgress const p) { printf(layer%ls status%d %llu/%llu\n, p.Id().c_str(), static_castint(p.Status()), p.CurrentBytes(), p.TotalBytes()); }); co_await pull;进度回调中拿到的ImageProgress是另一个数据类详见 imageprogress.md其Status()对应 C ABI 的WslcImageProgressStatus枚举wslcsdk.hUnknown、PullingPulling fs layer、Waiting、Downloading、Verifying Checksum、Extracting、CompletePull complete。镜像推送PushImageOptionsPushImageOptions是推送镜像时的参数载体。C ABI 结构体WslcPushImageOptionswslcsdk.h形状为{ image, registryAuth, progressCallback, progressCallbackContext }字段类型说明imagePCSTR要推送的镜像名必填registryAuthPCSTR必填Base64 编码的X-Registry-Auth请求头值progressCallbackWslcContainerImageProgressCallback进度回调可选progressCallbackContextPVOID回调上下文可选与拉取不同推送要求必须提供认证信息。在 PushImageOptions.cpp 中构造函数和两个 setter 都会校验image为空抛hresult_invalid_argumentImage cannot be emptyregistryAuth为空抛hresult_invalid_argumentRegistry auth cannot be empty。同样遵守使用后锁定规则——ToStruct()一旦执行再修改属性会抛hresult_illegal_state_change。PushImageOptions pushOptions{ Lmyapp:v1, Lbase64 X-Registry-Auth }; co_await session.PushImageAsync(pushOptions);registryAuth的典型来源是Session::Authenticate(serverAddress, username, password)该方法调用 C ABI 的WslcSessionAuthenticate返回 Base64 编码的 JSON 认证令牌形如{identitytoken: ...}或{username: ..., password: ...}可直接作为PushImageOptions::RegistryAuth以及上文的PullImageOptions::RegistryAuth使用其详细语义在 wslcsdk.h 的注释中有完整说明。镜像打标签TagImageOptionsTagImageOptions用于给已有镜像添加标签。C ABI 结构体WslcTagImageOptionswslcsdk.h形状为{ image, repo, tag }三个字段全部必填字段类型说明imagePCSTR源镜像名或 IDrepoPCSTR目标仓库名tagPCSTR目标标签名TagImageOptions.cpp 中构造函数对三个参数逐一校验任一为空都会抛hresult_invalid_argument。注意与拉取/推送不同TagImageOptions的转换方法是ToStructPointer()返回WslcTagImageOptions*直接供 Session.cpp 中的Session::TagImage调用WslcTagSessionImage使用。TagImageOptions tagOptions{ Lalpine:latest, Lmyregistry.local/alpine, Lprod }; session.TagImage(tagOptions);Session::TagImage是同步方法返回void不需要co_await而PullImageAsync/PushImageAsync返回IAsyncActionWithProgressImageProgress支持异步与进度订阅。这一差异在 Session.h 的声明中可见。虚拟磁盘卷VhdOptions属性集与默认值VhdOptions描述要创建的 VHD/VHDX 虚拟磁盘卷的规格。它被两个场景引用Session::CreateVhdVolume(VhdOptions)为会话创建命名的虚拟磁盘卷SessionSettings::VhdRequirements(VhdOptions)设定会话创建时默认生成的存储卷规格属性见 VhdOptions.h 与 wslcsdk.idl属性类型默认值说明NameString空卷名SizeUInt64s_DefaultStorageSize32 GiB卷大小单位字节不可为 0TypeVhdTypeDynamicDynamic动态扩容 VHDX或Fixed固定分配 VHDXOwnerIReferenceVhdOwnernullptr卷根 inode 的 uid/gidmkfs 时生效可选VhdType与VhdOwner定义在 wslcsdk.idlVhdType只有Dynamic 0与Fixed 1VhdOwner是含Uid、Gid两个UInt32字段的简单结构体。默认的 32 GiB 大小定义在 Defaults.hs_DefaultStorageSize 32ULL * 1024 * 1024 * 1024而默认Dynamic类型则直接写在VhdOptions的成员初始化处VhdOptions.h。校验与 C ABI 映射VhdOptions.cpp 的约束构造函数与Sizesetter 均校验size 不得为 0否则抛hresult_invalid_argumentVHD size cannot be zero与其他选项类一致使用后锁定ToStructPointer()后任何属性修改抛hresult_illegal_state_changeOwner是可空的IReferenceVhdOwner仅在显式设置时才生效。ToStructPointer()VhdOptions.cpp生成WslcVhdRequirements结构体字段映射如下结构体定义见 wslcsdk.hname←NamesizeBytes←Sizetype←Type强转为WslcVhdTypeWSLC_VHD_TYPE_DYNAMIC 0/WSLC_VHD_TYPE_FIXED 1uid/gid←Owner.Uid/Owner.Gid并且通过WI_SetFlag置位WSLC_VHD_REQ_FLAG_OWNER 0x00000001标志该标志表示 uid/gid 字段有效C 层的WslcCreateSessionVhdVolumewslcsdk.cpp会校验已知标志位并仅在WSLC_VHD_REQ_FLAG_OWNER置位时使用 uid/gidwslcsdk.cpp。在会话设置与卷创建中的两种用法// 用法一创建独立命名卷Dynamic 类型8 GiB VhdOptions vhdOptions{ Ldata-volume, 8ULL * 1024 * 1024 * 1024, VhdType::Dynamic }; session.CreateVhdVolume(vhdOptions); // 用法二通过 SessionSettings 定制会话默认存储卷 SessionSettings settings{ LMyApp, LC:\\WslcData }; VhdOptions req{ Ldefault, 64ULL * 1024 * 1024 * 1024, VhdType::Fixed }; settings.VhdRequirements(req); Session session{ settings }; session.Start();注意两点一是SessionSettings::VhdRequirementssetter 在会话初始化ToStructPointer首次调用后不可再改否则抛hresult_illegal_state_changeSessionSettings.cpp二是根据 wslcsdk.idl 的注释Owner仅支持命名卷即CreateVhdVolume场景把它设置在SessionSettings的VhdOptions上会在属性设置时以E_INVALIDARG失败。版本查询ServiceVersionServiceVersion是WslcService::GetVersion()的返回类型封装 WSL 容器运行时版本号属性为Major()、Minor()、Revision()三个uint32_t见 ServiceVersion.h。它的 C 形状是 wslcsdk.h 中的WslcVersion { major, minor, revision }。调用链路清晰可见WslcService::GetVersion()WslcService.cpp先通过winrt::check_hresult(WslcGetVersion(version))调用 C ABI 获取版本再用winrt::makeimplementation::ServiceVersion(version.major, version.minor, version.revision)构造 WinRT 对象。C ABI 的WslcGetVersionwslcsdk.cpp则进一步从IWSLCCompatSessionManager::GetVersion获取WSLCCompatVersion把Major/Minor/Revision拷贝进输出结构体。auto version WslcService::GetVersion(); printf(WSL container runtime version: %u.%u.%u\n, version.Major(), version.Minor(), version.Revision());整合到完整容器生命周期上述数据类并不是孤立存在的它们共同服务于创建会话 → 管理镜像 → 运行容器的完整流程。仓库中的 end-to-end-example.md 给出了一个端到端示例其中PullImageOptions的用法拉取alpine:latest后创建并运行容器完整呈现了这些选项类在真实场景中的位置init_apartment(); // 检查前置组件并打印版本ServiceVersion 使用处 auto missing WslcService::GetMissingComponents(); if (missing ! static_castComponent(0)) { printf(WSL components are missing. Run: wsl --install\n); return 1; } auto ver WslcService::GetVersion(); printf(WSL version: %u.%u.%u\n, ver.Major(), ver.Minor(), ver.Revision()); // 创建会话 SessionSettings sessionSettings{ LMyApp, LC:\\WslcData }; sessionSettings.CpuCount(4); sessionSettings.MemorySizeInMB(4096); Session session{ sessionSettings }; session.Start(); // 拉取镜像PullImageOptions 使用处 PullImageOptions pullOpts{ Ldocker.io/library/alpine:latest }; auto pullOp session.PullImageAsync(pullOpts); co_await pullOp; // ... 配置 init 进程、创建并启动容器、等待退出、清理 ... session.Terminate();工程集成与最佳实践如何在项目中引用 SDKMicrosoft.WSL.Containers以 NuGet 包形式分发仓库中 nuget/Microsoft.WSL.Containers 有完整说明C/WinRT 用法#include winrt/Microsoft.WSL.Containers.hMSBuild C/WinRT包会自动引用Microsoft.WSL.Containers.winmd生成投影头文件并向二进制注入激活清单使RoGetActivationFactory无需 COM 注册即可把类解析到wslcsdk.dll可用WslcEnableCppWinRTfalse/WslcEnableCppWinRT关闭该集成。MSBuild C#.NET 8自动引用wslcsdkcs.dll投影程序集using Microsoft.WSL.Containers;后即可使用同名 API。CMakefind_package(Microsoft.WSL.Containers REQUIRED)后target_link_libraries(my_app PRIVATE Microsoft.WSL.Containers::SDK)。纯 C/C 调用则直接#include wslcsdk.h链接wslcsdk.lib使用WslcPullSessionImage等导出函数导出表见 wslcsdk.def。注意该 SDK 当前处于Preview状态API 可能在后续版本中发生破坏性变更请勿在生产负载中依赖其稳定性。使用选项类时的一致性要点结合 referenced.md 的原始说明与上述源码分析可以归纳出以下实践准则先配置、后传参所有选项类在ToStruct()/ToStructPointer()后即锁定任何后续属性修改都会抛hresult_illegal_state_change。必填项校验发生在对象构造/setter 阶段PullImageOptions::Uri、PushImageOptions::Image与RegistryAuth、TagImageOptions的三个字段、VhdOptions::Size非零都在赋值时校验空值/零值会立即抛hresult_invalid_argument便于尽早发现调用错误。同步与异步的分工拉取、推送以及导入、加载走IAsyncActionWithProgressImageProgress异步路径并支持进度订阅打标签、创建 VHD 卷是同步调用版本查询是静态同步方法。认证信息复用Session::Authenticate返回的认证令牌是PullImageOptions::RegistryAuth与PushImageOptions::RegistryAuth的标准输入推送时必填拉取私有仓库时必填。错误处理统一C/WinRT 投影的错误统一以winrt::hresult_error抛出底层 C ABI 的 HRESULT 与可读错误消息errorMessage会被THROW_MSG_IF_FAILED合并后转为异常无需开发者手动处理PWSTR错误缓冲区。通过合理组合这五个数据类你可以在自己的应用中完整实现拉取镜像 → 打标签 → 推送镜像 → 创建存储卷 → 运行容器的容器工作流并借助统一的校验与错误处理机制获得清晰的失败反馈。【免费下载链接】WSLWindows Subsystem for Linux项目地址: https://gitcode.com/GitHub_Trending/ws/WSL创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考