news 2026/9/10 9:52:40

WSL C API 深度解析:用 PullImageOptions 从容器镜像仓库拉取镜像

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
WSL C API 深度解析:用 PullImageOptions 从容器镜像仓库拉取镜像

WSL C# API 深度解析:用 PullImageOptions 从容器镜像仓库拉取镜像

【免费下载链接】WSLWindows Subsystem for Linux项目地址: https://gitcode.com/GitHub_Trending/ws/WSL

本文围绕 WSL(Windows Subsystem for Linux)WSLC(Windows Subsystem for Linux Containers)SDK 的 C# 配置类PullImageOptions展开,说明其两个核心属性UriRegistryAuth的用法、底层 C 结构体映射关系,以及Session.PullImage/PullImageAsync的调用链与错误语义。读完后可掌握如何用 C# 从公共或私有镜像仓库拉取容器镜像、处理拉取进度事件,并理解该选项类在 WinRT 层与 C API 之间的转换机制。

类定义与基本用法

PullImageOptions是 C# API 设置类之一,用于描述"从镜像仓库拉取镜像"操作的参数。其完整定义为:

public sealed class PullImageOptions { public PullImageOptions(string uri); public string Uri { get; set; } public string RegistryAuth { get; set; } }

最小使用示例(来自 官方文档):

var pullOptions = new PullImageOptions("docker.io/library/alpine:latest") { RegistryAuth = string.Empty // optional for public registries };

要点:

  • 构造函数的uri参数是唯一的必选项,指定要拉取的镜像地址,通常包含registry/namespace/image:tag形式(如docker.io/library/alpine:latest,以及本地 registry 的localhost:5000/hello-world:latest);
  • RegistryAuth对公共仓库可省略(置为空字符串即可匿名拉取),拉取私有仓库镜像时必须提供认证凭据。

属性语义:从源码确认的约束

WinRT 实现位于 PullImageOptions.cpp 与 PullImageOptions.h,可从中确认以下行为约束:

  1. Uri不可为空。构造函数和 setter 都会检查:

    if (uri.empty()) { throw hresult_invalid_argument(L"URI cannot be empty"); }

    即传入空字符串会抛出hresult_invalid_argument(C# 中表现为ArgumentException)。

  2. 选项类是"一次应用后冻结"的。两个属性的 setter 在选项已被 SDK 消费后(内部m_pullImageOptions已分配)都会拒绝修改:

    if (m_pullImageOptions) { throw hresult_illegal_state_change(L"Cannot change value after options have been applied"); }

    这意味着一个PullImageOptions实例参与拉取操作后不应再被修改复用,如需不同参数应新建实例。

  3. RegistryAuth为空串等价于匿名拉取。在转换为 C 结构体时:

    m_pullImageOptions->registryAuth = m_registryAuth.empty() ? nullptr : m_registryAuth.c_str();

    空串会被转换为nullptr,与 C 结构体中registryAuth字段标注的_In_opt_(可选)一致。

底层映射:WinRT 选项类到 WslcPullImageOptions 结构体

C# 层的PullImageOptions最终通过ToStruct()转换为 C API 的结构体 WslcPullImageOptions,定义于 wslcsdk.h:

typedef struct WslcPullImageOptions { _In_z_ PCSTR uri; WslcContainerImageProgressCallback progressCallback; PVOID progressCallbackContext; _In_opt_z_ PCSTR registryAuth; } WslcPullImageOptions; STDAPI WslcPullSessionImage(_In_ WslcSession session, _In_ const WslcPullImageOptions* options, _Outptr_opt_result_z_ PWSTR* errorMessage);
C 字段说明C# 对应
uri_In_z_,必填)镜像地址Uri属性
registryAuth_In_opt_,可选)仓库认证凭据RegistryAuth属性
progressCallback/progressCallbackContext进度回调C# 层不直接暴露,见下文PullImageAsync

注意 WinRT 转换实现中有两处细节(PullImageOptions.cpp):

  • ToStruct()惰性且幂等的:首次调用时分配结构体并写入字段,之后重复调用返回同一缓存结构体的引用;
  • 结构体中的progressCallback被置为nullptr——C# 用户不通过函数指针接收进度,而是走PullImageAsyncIAsyncActionWithProgress事件通道。

对应的拉取接口在 IDL 中声明(wslcsdk.idl):

void PullImage(PullImageOptions options); Windows.Foundation.IAsyncActionWithProgress<ImageProgress> PullImageAsync(PullImageOptions options);

即同步与异步两个入口,PullImageOptions运行时类定义于 wslcsdk.idl:

runtimeclass PullImageOptions { PullImageOptions(String uri); String Uri; String RegistryAuth; };

拉取进度:ImageProgress 与 ImageProgressStatus

异步拉取会回调进度事件,进度类型为 ImageProgress,字段为Id(层 ID 或 digest)、StatusCurrentBytesTotalBytesStatus对应 C 层枚举(wslcsdk.h),与docker pull的常见输出阶段一一对应:

typedef enum WslcImageProgressStatus { WSLC_IMAGE_PROGRESS_STATUS_UNKNOWN = 0, WSLC_IMAGE_PROGRESS_STATUS_PULLING = 1, // "Pulling fs layer" WSLC_IMAGE_PROGRESS_STATUS_WAITING = 2, // "Waiting" WSLC_IMAGE_PROGRESS_STATUS_DOWNLOADING = 3, // "Downloading" WSLC_IMAGE_PROGRESS_STATUS_VERIFYING = 4, // "Verifying Checksum" WSLC_IMAGE_PROGRESS_STATUS_EXTRACTING = 5, // "Extracting" WSLC_IMAGE_PROGRESS_STATUS_COMPLETE = 6 // "Pull complete" } WslcImageProgressStatus;

完整实战:创建会话并异步拉取镜像

端到端示例演示了PullImageOptions在完整生命周期中的位置:

// 1. 创建会话(4 CPU / 4 GB 内存) var sessionSettings = new SessionSettings("MyApp", @"C:\WslcData") { CpuCount = 4, MemorySizeInMB = 4096 }; var session = new Session(sessionSettings); session.Start(); // 2. 拉取镜像并输出进度 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. 用拉下来的镜像创建容器 var containerSettings = new ContainerSettings("alpine:latest") { Name = "hello-container", InitProcess = new ProcessSettings { CommandLine = new[] { "/bin/echo", "Hello from WSL Container!" }, OutputMode = ProcessOutputMode.Event } }; var container = session.CreateContainer(containerSettings); container.Start();

仓库中的 WSLC-NextCloud 示例则展示了同步版本的简写用法:session.PullImage(new PullImageOptions(imageName))——公共仓库镜像只需提供 URI 一个参数即可完成拉取。

错误语义与私有仓库认证(测试用例佐证)

单元测试 WslcSdkTests.cpp 的PullImage测试方法用真实场景验证了该选项类的边界行为,可据此建立可预期的错误处理:

场景结果
从本地 registry 真实拉取镜像(先删除本地镜像确保是真实拉取)成功,HasImage校验通过,且拉取后可直接运行容器(输出 "Hello from Docker!")
拉取 registry 中不存在的镜像返回WSLC_E_IMAGE_NOT_FOUND
urinullptr返回E_INVALIDARG
私有 registry 未提供凭据WslcPullSessionImage返回E_FAIL并输出错误信息
提供错误凭据返回E_FAIL

对于私有仓库,测试用例(WslcSdkTests.cpp)展示了推荐凭据流:先调用WslcSessionAuthenticate换取认证串,其输出可以不做任何转换直接作为registryAuth传入

VERIFY_SUCCEEDED(WslcSessionAuthenticate( m_defaultSession, registryAddress.c_str(), c_username, c_password, &authToken, nullptr, nullptr)); WslcPullImageOptions opts{}; opts.uri = image.c_str(); opts.registryAuth = authToken.get(); VERIFY_SUCCEEDED(WslcPullSessionImage(m_defaultSession, &opts, nullptr));

即 C# 场景下的组合模式为:Session.Authenticate(...)获得认证结果 → 将其赋给PullImageOptions.RegistryAuth→ 调用PullImageAsync。这与 C 层registryAuth标注为_In_opt_且测试注释"output can be passed as registryAuth without any transformation"相吻合。

小结与相关文档

  • PullImageOptions仅两个属性:Uri(必填、不可为空)与RegistryAuth(可选,空串等价匿名拉取);
  • 选项类在参与一次拉取应用后应视为冻结,修改属性会抛hresult_illegal_state_change
  • 异步拉取通过PullImageAsyncIAsyncActionWithProgress<ImageProgress>获得与docker pull一致的阶段化进度(Pulling/Downloading/Verifying/Extracting/Complete);
  • 错误语义已被单元测试覆盖:镜像不存在返回WSLC_E_IMAGE_NOT_FOUND,参数非法返回E_INVALIDARG,凭据错误返回E_FAIL

可继续深入的相关文档:

  • C# API 总览 与 Session 核心类
  • C API 的 WslcPullImageOptions 结构体 与 WslcPullSessionImage
  • PushImageOptions、TagImageOptions(拉取/推送/打标构成镜像管理闭环)
  • C++ 端到端示例(对照同构的 C++ 拉取流程)

【免费下载链接】WSLWindows Subsystem for Linux项目地址: https://gitcode.com/GitHub_Trending/ws/WSL

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/10 9:50:47

数字员工与SaaW落地全解:从概念到商业价值的实践指南

最近朋友圈里最热闹的To B话题&#xff0c;绕不开“数字员工”和“SaaW”这两个词。我拿到了一份《全球真实数字员工与 SaaW 商业全景报告 2026-1》&#xff0c;翻了几遍之后又对照自己过去在几家制造、零售企业里落地数字员工项目的经验&#xff0c;发现很多内容不能只看结论&…

作者头像 李华