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

资讯详情

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

WSL 容器镜像进度回调数据结构 WslcImageProgressMessage 完全解析

WSL 容器镜像进度回调数据结构 WslcImageProgressMessage 完全解析 WSL 容器镜像进度回调数据结构 WslcImageProgressMessage 完全解析【免费下载链接】WSLWindows Subsystem for Linux项目地址: https://gitcode.com/GitHub_Trending/ws/WSLWslcImageProgressMessage是 Windows Subsystem for LinuxWSL容器 SDKWSLC SDK中用于在镜像拉取Pull、推送Push、导入Import等长时间操作期间向上层应用报告逐层进度的核心结构体。本文以 wslcimageprogressmessage.md 为骨架结合 wslcsdk.h、ProgressCallback.cpp 与 WslcSdkTests.cpp 等源码实现完整讲解该结构体的字段语义、状态机取值、触发机制与实战用法帮助你写出可正确渲染 docker 风格进度条的集成代码。结构体概览一次回调的三个信息维度WslcImageProgressMessage是 SDK 提供给调用方通过WslcContainerImageProgressCallback回调函数的只读进度快照其定义位于 wslcsdk.htypedef struct WslcImageProgressMessage { _Out_ PCSTR id; // layer ID or digest _Out_ WslcImageProgressStatus status; // Downloading, Extracting, etc. _Out_ WslcImageProgressDetail detail; } WslcImageProgressMessage;字段类型语义idPCSTR当前进度所对应的镜像层 ID 或摘要layer ID or digeststatusWslcImageProgressStatus当前层所处的阶段如 Downloading、Extracting 等detailWslcImageProgressDetail字节级进度明细含已下载/总字节数三个字段恰好构成一个「哪一层、处于什么阶段、完成了多少」的完整进度三元组id回答哪个层status回答进行到哪一步detail回答进度到百分之几。UI 层拿到一条消息即可独立渲染一行进度无需维护额外状态。字段详解id镜像层的身份标识id是PCSTR指向以 NUL 结尾的 ANSI 字符串的常量指针携带当前进度消息所属镜像层的layer ID 或 digest。在多层镜像如 alpine 这类多 fs layer 镜像的拉取过程中同一镜像的不同层会各自触发独立的消息层与层之间依靠id区分。因此做去重/合并 UI 时应使用id作为哈希表键打印日志时id应作为首列输出便于对照 docker 的经典输出格式。status镜像层生命周期阶段status的类型是WslcImageProgressStatus一个定义在同头文件中的枚举wslcsdk.htypedef 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;枚举值数值对应引擎字符串含义WSLC_IMAGE_PROGRESS_STATUS_UNKNOWN0无法识别兜底状态表示引擎字符串未能映射到已知阶段WSLC_IMAGE_PROGRESS_STATUS_PULLING1Pulling fs layer / Pulling from 前缀正在拉取文件系统层WSLC_IMAGE_PROGRESS_STATUS_WAITING2Waiting层排队等待下载WSLC_IMAGE_PROGRESS_STATUS_DOWNLOADING3Downloading正在下载此时detail的字节数持续增长WSLC_IMAGE_PROGRESS_STATUS_VERIFYING4Verifying Checksum / Digest: 前缀校验和验证 / 摘要计算WSLC_IMAGE_PROGRESS_STATUS_EXTRACTING5Extracting正在解压层内容WSLC_IMAGE_PROGRESS_STATUS_COMPLETE6Pull complete / Download complete / Status: 前缀该层拉取完成这些状态与 Docker CLI 拉取镜像时输出的Pulling fs layer→Waiting→Downloading→Verifying Checksum→Extracting→Pull complete流程一一对应SDK 在底层把引擎字符串归一化成了稳定的枚举值。detail字节级进度明细detail的类型是WslcImageProgressDetailwslcimageprogressdetail.md定义于 wslcsdk.htypedef struct WslcImageProgressDetail { _Out_ uint64_t currentBytes; // bytes downloaded so far _Out_ uint64_t totalBytes; // total bytes expected } WslcImageProgressDetail;字段类型语义currentBytesuint64_t截至目前已下载的字节数totalBytesuint64_t该层预期总字节数totalBytes在下载开始前如PULLING/WAITING阶段可能为 0 或未知UI 在totalBytes 0时应显示为不确定进度如转圈动画而非除零错误当currentBytes totalBytes且状态为COMPLETE时该层完成。两个字段均为uint64_t对镜像层这种动辄数百 MB 的场景不会溢出。消息从哪里来回调触发机制与引擎字符串映射WslcImageProgressMessage并不会由调用方构造而是由 SDK 内部的ProgressCallback类从容器运行时引擎的输出中翻译而来ProgressCallback.cppHRESULT STDMETHODCALLTYPE ProgressCallback::OnProgress(LPCSTR Status, LPCSTR Id, ULONGLONG Current, ULONGLONG Total) { if (m_callback) { WslcImageProgressMessage message{}; message.id Id; message.status ConvertStatus(Status); message.detail.currentBytes Current; message.detail.totalBytes Total; return m_callback(message, m_context); } return S_OK; }关键点在于ConvertStatusProgressCallback.cpp——SDK 使用一组字符串到枚举的映射宏把引擎发来的原始文本归一化精确匹配Pulling fs layer→PULLING、Waiting→WAITING、Downloading→DOWNLOADING、Download complete→COMPLETE、Verifying Checksum→VERIFYING、Extracting→EXTRACTING、Pull complete→COMPLETE前缀匹配Pulling from →PULLING、Digest: →VERIFYING、Status: →COMPLETE无法识别的字符串统一落到WSLC_IMAGE_PROGRESS_STATUS_UNKNOWN0并输出调试日志UnknownImageProgressStatus。也就是说在回调里拿到的status永远是上述 7 个枚举值之一而不是未经加工的引擎文本。源码注释也坦承这种字符串映射方式略显脆弱fragile并建议为每个状态补充显式测试见 ProgressCallback.cpp 的 TODO因此上层应用不应假设引擎字符串集合固定不变而应始终以枚举值为准、以UNKNOWN为兜底。端到端使用示例为拉取镜像挂载进度回调WslcImageProgressMessage的生命周期由WslcPullSessionImagewslcpullsessionimage.md、WslcPushSessionImagewslcpushsessionimage.md、WslcImportSessionImage等镜像管理 API 驱动这些 API 的 Options 结构WslcPullImageOptions、WslcPushImageOptions、WslcImportImageOptions、WslcLoadImageOptions都接受一个progressCallback字段类型为 WslcContainerImageProgressCallbacktypedef HRESULT(CALLBACK* WslcContainerImageProgressCallback)(const WslcImageProgressMessage* progress, PVOID context);回调函数接收const WslcImageProgressMessage*SDK 构造的进度快照与调用方自定义的context透传指针可用于传入 UI 句柄或进度条对象。以下示例取自 wslcpullsessionimage.md演示如何打印逐层进度HRESULT CALLBACK OnImageProgress(const WslcImageProgressMessage* progress, PVOID context) { UNREFERENCED_PARAMETER(context); printf(%s %llu/%llu\n, progress-id, (unsigned long long)progress-detail.currentBytes, (unsigned long long)progress-detail.totalBytes); return S_OK; } WslcPullImageOptions pullOptions { 0 }; pullOptions.uri docker.io/library/alpine:latest; pullOptions.progressCallback OnImageProgress; pullOptions.progressCallbackContext NULL; pullOptions.registryAuth NULL; HRESULT hr WslcPullSessionImage(session, pullOptions, NULL);要点说明回调签名返回HRESULT处理成功应返回S_OK测试与示例均如此约定每条消息只对一个层有效若镜像有 N 个层会收到 N 条不同id、各自独立推进的进度序列想渲染更丰富的 UI可同时消费status与detailDOWNLOADING时显示currentBytes/totalBytes的百分比条EXTRACTING时切换为解压中文案COMPLETE时将该层标记为完成若不需要进度将progressCallback置NULL即可SDK 内部会静默跳过见OnProgress中的空指针判断。推送方向的用法对称见 wslcpushsessionimage.mdWslcPushImageOptions pushOptions { 0 }; pushOptions.image demo/alpine:stable; pushOptions.registryAuth BASE64_X_REGISTRY_AUTH; pushOptions.progressCallback OnImageProgress; pushOptions.progressCallbackContext NULL; HRESULT hr WslcPushSessionImage(session, pushOptions, NULL);测试验证SDK 自带的进度回调测试仓库的 SDK 测试套件 WslcSdkTests.cpp 中专门实现了ImageProgressCallback测试方法可作为理解该结构体语义的权威参考auto progressCb [](const WslcImageProgressMessage* progress, PVOID context) - HRESULT { auto* ctx static_castProgressContext*(context); ctx-invoked true; if (progress ! nullptr progress-status ! WSLC_IMAGE_PROGRESS_STATUS_UNKNOWN) { ctx-sawKnownStatus true; } return S_OK; };该测试通过StartLocalRegistry()启动本地镜像仓库将测试镜像hello-world:latest打标签后推送到本地 registry从而触发真实的进度回调序列并断言回调确实被触发invoked置位回调中progress指针非空至少出现一个已知状态非WSLC_IMAGE_PROGRESS_STATUS_UNKNOWN。这从测试角度印证了正常拉取/推送流程中WslcImageProgressMessage会被持续产出且status字段在真实操作中几乎必然包含可识别的阶段值。测试还演示了通过context传入自定义结构体ProgressContext来汇总回调结果的典型模式——这正是progressCallbackContext字段的设计用途。与其他 API 的关系与调用方注意事项WslcImageProgressMessage处于 WSLC SDK 镜像管理回调链的中间位置上游WslcImageProgressStatus枚举wslcimageprogressstatus.md与WslcImageProgressDetail结构体wslcimageprogressdetail.md是它的两个成员类型下游它作为const指针参数被 WslcContainerImageProgressCallback 消费进而被WslcPullImageOptions、WslcPushImageOptions、WslcImportImageOptions、WslcLoadImageOptions等 Options 结构的progressCallback字段引用跨语言在 WinRT 层ImageProgress.h存在对应的ImageProgress包装类以ImageProgressStatus、CurrentBytes、TotalBytes属性呈现同样的三个信息维度供 C#/WinRT 应用使用。编写回调时请记住消息是临时的、只读的progress指针指向 SDK 内部的栈上对象WslcImageProgressMessage message{}仅在本次回调调用期间有效需要保留数据时必须拷贝到自己的上下文同一层会有多条消息从DOWNLOADING到COMPLETE通常不止一次回调UI 应按idstatus增量更新而非整行重绘UNKNOWN是合法状态当引擎字符串无法映射时会出现UI 应优雅降级显示原始信息或忽略totalBytes可能为 0进度百分比计算需做除零保护回调应快速返回它在 SDK 处理引擎输出的路径上同步执行耗时操作应投递到其他线程避免阻塞拉取流程。掌握了WslcImageProgressMessage的字段语义、状态机与回调时序你就能在自己的工具链中复刻 docker CLI 级别的镜像操作进度体验或基于id/status/detail构建自定义的拉取监控、日志与统计系统。【免费下载链接】WSLWindows Subsystem for Linux项目地址: https://gitcode.com/GitHub_Trending/ws/WSL创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表