WSL 容器 SDK 镜像管理指南:WslcDeleteSessionImage 删除会话镜像 API 详解
2026/9/10 13:46:08 网站建设 项目流程

WSL 容器 SDK 镜像管理指南:WslcDeleteSessionImage 删除会话镜像 API 详解

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

WslcDeleteSessionImage是 Windows Subsystem for Linux(WSL)容器 SDK(WslcSDK)中负责从会话(Session)内删除容器镜像的 C 语言 API。本文以官方 API 参考文档 wslcdeletesessionimage.md 为核心,结合仓库内 SDK 头文件、实现源码与测试用例,讲解该 API 的函数签名、参数语义、错误码、完整调用示例及其底层实现原理,帮助开发者正确地在 WSL 容器应用中管理镜像生命周期。

功能定位:镜像生命周期中的"删除"环节

在 WSL 容器 SDK 中,镜像(Image)是创建容器的模板。SDK 围绕镜像提供了一整套生命周期管理 API,见 image-apis/index.md:

  • 拉取与导入:WslcPullSessionImageWslcImportSessionImageWslcImportSessionImageFromFile
  • 加载:WslcLoadSessionImageWslcLoadSessionImageFromFile
  • 删除:WslcDeleteSessionImage(本文主角)
  • 查询:WslcListSessionImages
  • 打标签与推送:WslcTagSessionImageWslcPushSessionImage

WslcDeleteSessionImage即其中"删除"一环,用于从指定会话中移除不再需要的镜像或镜像标签,释放磁盘与元数据空间。例如当开发者完成demo/imported:latest镜像的验证后,即可调用本 API 将其清理掉。

需要特别提醒:根据 wslcsdk.h 文件头部的 PREVIEW NOTICE,整个 WSL 容器 SDK 当前仍处于预览阶段,API 可能在未来的版本中发生破坏性变更,请勿在正式生产负载中依赖其稳定性。

函数签名与参数详解

WslcDeleteSessionImage的完整声明位于 wslcsdk.h,签名如下:

STDAPI WslcDeleteSessionImage( _In_ WslcSession session, _In_z_ PCSTR nameOrID, _Outptr_opt_result_z_ PWSTR* errorMessage);

各参数含义与方向如下表所示:

参数类型方向说明
sessionWslcSessionin目标会话句柄,必须是由WslcCreateSession创建且仍然有效的会话
nameOrIDPCSTRin要删除的镜像名称(如"repo:tag")或镜像 ID,ANSI 字符串
errorMessagePWSTR*out, optional可选输出参数;失败时返回详细的错误信息字符串(宽字符,以\0结尾),可传NULL忽略

函数返回值为HRESULT类型,S_OK表示删除成功。

其中nameOrID支持两种定位方式:

  • 镜像名称:形如"hello-world:latest""demo/imported:latest""debian:sdk-test-tag"仓库:标签格式。测试用例 WslcSdkTests.cpp 中即使用该格式删除镜像。
  • 镜像 ID:由WslcImageInfo.sha256字段(32 字节 SHA-256 摘要)标识的镜像唯一 ID,测试用例中以image.c_str()(从列表查询得到的 ID 字符串)传入删除,见 WslcSdkTests.cpp。

从数据结构看,镜像名长度上限为WSLC_IMAGE_NAME_LENGTH(255 个字符 + 结束符\0),见 wslcsdk.h。

返回值与错误码

作为HRESULT返回值的 API,调用方必须通过SUCCEEDED(hr)/FAILED(hr)宏判断结果。结合头文件定义与测试用例,可以归纳出以下关键返回值:

HRESULT含义依据
S_OK删除成功WslcSdkTests.cpp 正向用例
E_POINTER传入的nameOrIDNULL实现中的RETURN_HR_IF_NULL(E_POINTER, nameOrID),见 wslcsdk.cpp;测试见 WslcSdkTests.cpp
HRESULT_FROM_WIN32(ERROR_INVALID_STATE)会话句柄内部状态无效(如已被终止)wslcsdk.cpp
WSLC_E_IMAGE_NOT_FOUND0x80040601指定的镜像或标签不存在头文件宏定义见 wslcsdk.h;删除不存在的镜像返回该错误码,见 WslcSdkTests.cpp

此外,wslcsdk.h 还定义了一系列 WSL 容器专属错误码(WSLC_E_BASE = 0x0600起),包括WSLC_E_CONTAINER_NOT_FOUNDWSLC_E_SESSION_NOT_FOUNDWSLC_E_VOLUME_NOT_FOUND等,删除操作可能间接返回其中部分错误码(例如会话对应状态异常时)。建议调用方对HRESULT进行统一记录以便排查。

关于errorMessage:当传入非NULL指针且操作失败时,SDK 会通过内部的ErrorInfoWrapper填充人类可读的错误描述。测试用例 WslcSdkTests.cpp 验证了失败场景下errorMsg非空且可被日志输出。调用方在成功返回后无需处理该字符串;失败时若不再使用,应释放其内存(SDK 中此类输出字符串通常由CoTaskMemAlloc分配,应配合CoTaskMemFree释放)。

完整可运行的 C 示例

原 API 文档给出了最小示例:

HRESULT hr = WslcDeleteSessionImage(session, "demo/imported:latest", NULL);

但在真实应用中,session需要先通过会话创建流程获得。结合 wslcsdk.h 中WslcInitSessionSettingsWslcCreateSessionWslcReleaseSession的声明,下面给出一个带完整错误处理的实战示例:

#include <windows.h> #include <wslcsdk.h> HRESULT DeleteImageDemo(void) { HRESULT hr; // 1. 初始化会话设置(名称 + 存储路径) WslcSessionSettings sessionSettings; hr = WslcInitSessionSettings(L"demo-session", L"C:\\wslc\\demo", &sessionSettings); if (FAILED(hr)) { return hr; } // 2. 创建会话 WslcSession session = nullptr; wil::unique_cotaskmem_string errorMessage; hr = WslcCreateSession(&sessionSettings, &session, &errorMessage); if (FAILED(hr)) { // errorMessage 中包含失败原因描述 return hr; } // 3. 删除镜像(按名称,tag 指向的镜像层若被其他标签引用,仅移除该标签) hr = WslcDeleteSessionImage(session, "demo/imported:latest", &errorMessage); if (FAILED(hr)) { // 常见失败:WSLC_E_IMAGE_NOT_FOUND(镜像不存在)、E_POINTER(名称/ID 为 NULL) return hr; } // 4. 释放会话句柄 hr = WslcReleaseSession(session); return hr; }

要点说明:

  • 会话创建后即可反复执行镜像操作;删除镜像后再创建的容器将无法引用该镜像(WslcCreateContainer对不存在的镜像会返回WSLC_E_IMAGE_NOT_FOUND,参见 WslcSdkTests.cpp)。
  • errorMessage每次调用前可复用同一个wil::unique_cotaskmem_string管理内存,SDK 内部会正确处理其生命周期。

源码级实现剖析

WslcDeleteSessionImage的实现位于 wslcsdk.cpp,核心调用链如下:

  1. 错误信息包装:创建ErrorInfoWrapper errorInfoWrapper{errorMessage},将调用方传入的errorMessage输出指针接入统一错误收集机制。
  2. 会话有效性校验:通过CheckAndGetInternalType(session)取得会话内部类型,若底层session为空则返回HRESULT_FROM_WIN32(ERROR_INVALID_STATE)
  3. 参数校验nameOrIDNULL时直接返回E_POINTER
  4. 构造删除选项:填充WSLCCompatDeleteImageOptions options{}并将options.Image置为nameOrID。从源码注释// TODO: Flags? (Force and NoPrune)可以看出,当前公开版本只支持按名称/ID 定位删除,尚未暴露强制删除(Force)与不清理(NoPrune)等底层 Docker 兼容选项,这是可以合理推断的后续演进方向。
  5. 下发底层实现:调用internalType->session->DeleteImage(&options, &deletedImageInformation, deletedImageInformation.size_address<ULONG>()),由会话层完成实际删除,并收集被删除镜像的信息数组。
  6. 结果汇总:通过errorInfoWrapper.CaptureResult(...)将底层HRESULT结果与错误信息统一返回给调用方。

此外:

  • 该函数通过 wslcsdk.def 导出为 DLL 公共接口,可供链接wslcsdk.lib的应用程序调用。
  • SDK 同时提供 WinRT 封装层,在 winrt/Session.cpp 中可见Session::DeleteImage的对应实现,说明该能力同时暴露给 C++/WinRT 调用方。

测试验证与行为边界

仓库测试 WslcSdkTests.cpp 中的ImageDelete测试用例清晰刻画了本 API 的行为边界:

WSLC_TEST_METHOD(ImageDelete) { VERIFY_IS_TRUE(HasImage("hello-world:latest")); // 正向:删除已存在的镜像 wil::unique_cotaskmem_string errorMsg; VERIFY_SUCCEEDED(WslcDeleteSessionImage(m_defaultSession, "hello-world:latest", &errorMsg)); // 验证镜像已从列表中移除 VERIFY_IS_FALSE(HasImage("hello-world:latest")); // 重新加载镜像,供后续测试使用 LoadTestImage("hello-world:latest"); // 负向:null 名称必须失败 VERIFY_ARE_EQUAL(WslcDeleteSessionImage(m_defaultSession, nullptr, nullptr), E_POINTER); }

由此可以确认以下行为:

  • 删除成功后可验证:删除后调用WslcListSessionImages(测试中的HasImage即基于镜像列表实现)将不再看到该镜像;
  • 空指针保护nameOrIDNULL必然返回E_POINTER,且不会产生副作用;
  • 不存在的镜像:按名称删除不存在的镜像返回WSLC_E_IMAGE_NOT_FOUND,见 WslcSdkTests.cpp;
  • 标签删除语义:在TagImage测试中,WslcDeleteSessionImage(m_defaultSession, "debian:sdk-test-tag", nullptr)被用作清理临时标签的手段,见 WslcSdkTests.cpp,说明该 API 同样适用于按标签删除——当同一镜像被多个标签引用时,删除单个标签不会影响其他标签下的镜像层数据(与 Docker 的 tag 删除语义一致,从代码调用关系与测试用途可以推断)。

此外,测试在镜像导入(WslcImportSessionImage)、拉取等用例的清理阶段大量使用本 API(如 WslcSdkTests.cpp),是验证镜像操作闭环的标准清理手段。

与镜像生命周期其他 API 的协同

一个典型的镜像管理流程可以这样组织:

  1. 获取镜像WslcPullSessionImage从仓库拉取,或WslcImportSessionImage/WslcLoadSessionImage从本地导入;
  2. 查询WslcListSessionImages枚举镜像列表(包含名称、SHA-256、大小与创建时间),用于确认删除目标;
  3. 打标签WslcTagSessionImage为镜像添加额外标签,便于按业务维度组织;
  4. 删除WslcDeleteSessionImage按名称或 ID 删除不再使用的镜像;
  5. 推送WslcPushSessionImage将本地镜像发布到远端仓库。

各 API 的详细签名可分别查阅同目录下的 wslcpullsessionimage.md、wslcimportsessionimage.md、wslclistsessionimages.md、wslctagsessionimage.md 与 wslcpushsessionimage.md。

注意事项与最佳实践

  1. 预览期约束:SDK 处于预览阶段,函数签名与行为可能变更,升级 SDK 版本后需回归验证删除逻辑(头文件声明见 wslcsdk.h)。
  2. 会话必须存活:删除操作依赖有效会话,会话已终止时返回ERROR_INVALID_STATE;用完会话记得WslcReleaseSession
  3. 名称/ID 的字符串编码nameOrID是 ANSI 字符串(PCSTR),而errorMessage是宽字符(PWSTR),混用时注意编码转换。
  4. 删除前确认:建议先调用WslcListSessionImages确认目标存在,避免对WSLC_E_IMAGE_NOT_FOUND的误判;删除操作不可撤销,请确认镜像确无容器引用后再清理。
  5. 错误信息日志化:生产代码中请把errorMessage记录进日志(测试中同样以LogInfo("Import error: %ws", errorMsg.get())方式输出),这能显著缩短排障时间。
  6. 引用计数语义:按标签删除只移除该标签;只有当镜像没有任何标签引用时,镜像数据才会被真正回收,这与底层容器运行时的镜像引用计数机制一致。

综上所述,WslcDeleteSessionImage是 WSL 容器 SDK 镜像管理中简单但高频的 API,掌握其参数语义、错误码与底层调用链,即可在容器应用中加入可靠的镜像清理能力。

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

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询