十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

WSL C SDK 镜像标记指南:深入解析 WslcTagSessionImage 的用法、参数与底层实现

WSL C SDK 镜像标记指南:深入解析 WslcTagSessionImage 的用法、参数与底层实现 WSL C SDK 镜像标记指南深入解析 WslcTagSessionImage 的用法、参数与底层实现【免费下载链接】WSLWindows Subsystem for Linux项目地址: https://gitcode.com/GitHub_Trending/ws/WSL导读WslcTagSessionImage是 Windows Subsystem for LinuxWSLC SDKWslcSDK中负责为容器镜像创建新标签tag的核心 API。在 WSL 容器工作流中拉取镜像WslcPullSessionImage之后、推送镜像WslcPushSessionImage之前通常需要先用它给镜像打上目标仓库前缀与语义化标签才能在本地镜像库中定位并发布镜像。本文将围绕该 API 的签名、参数、选项结构体、返回值与错误处理展开并结合本仓库的 C 层实现wslcsdk.cpp与单元测试WslcSdkTests.cpp剖析其底层调用链最终给出可直接复制的完整 C 示例代码帮助你快速掌握在 C/C 项目中为 WSL 容器镜像打标签的实战方法。API 签名与参数说明WslcTagSessionImage的完整函数签名如下声明见 wslcsdk.hSTDAPI WslcTagSessionImage( _In_ WslcSession session, _In_ const WslcTagImageOptions* options, _Outptr_opt_result_z_ PWSTR* errorMessage);参数类型方向说明sessionWslcSessionin目标 WSL 容器会话句柄由WslcCreateSession创建optionsconst WslcTagImageOptions*in标记配置指定源镜像名/ID、目标仓库与目标标签errorMessagePWSTR*out, optional失败时返回的本地化错误信息UTF-16 字符串可为NULL返回值HRESULT。S_OK表示标记成功失败时返回对应的错误码并通过errorMessage提供可读错误描述。参数语义session必须是有效会话。在 wslcsdk.cpp 的实现中函数首先通过CheckAndGetInternalType(session)解析句柄若底层会话对象为空立即返回HRESULT_FROM_WIN32(ERROR_INVALID_STATE)——这也提醒调用方任何图像管理 API 都必须先成功创建会话不能对无效会话调用。options指向WslcTagImageOptions结构体的指针。实现中会校验其三个字段image、repo、tag均非空任何一个为NULL都返回E_INVALIDARG详见后文错误处理。errorMessage可选输出参数。若传入非空指针SDK 会通过内部ErrorInfoWrapper捕获底层错误并将可读信息写入该缓冲区调用方应使用CoTaskMemFree释放。选项结构体 WslcTagImageOptions标记行为完全由WslcTagImageOptions结构体驱动定义见 wslctagimageoptions.mdtypedef struct WslcTagImageOptions { _In_z_ PCSTR image; // Source image name or ID. _In_z_ PCSTR repo; // Target repository name. _In_z_ PCSTR tag; // Target tag name. } WslcTagImageOptions;字段类型说明imagePCSTR源镜像名称或 ID例如docker.io/library/alpine:latestrepoPCSTR目标仓库名称例如demo/alpine或带注册表地址的localhost:5000/demo/alpinetagPCSTR目标标签名称例如stable三个字段组合后形成的新镜像引用即repo:tag。注意使用{ 0 }初始化结构体是一个好习惯能保证未赋值的字段为空指针从而让 SDK 的参数校验E_INVALIDARG在字段缺失时立即生效而不是携带未定义内存内容继续执行。字段均为 UTF-8 编码的 C 字符串PCSTR而errorMessage是 UTF-16PWSTR混合使用时要留意字符集差异。最小可运行示例文档给出的经典示例可直接编译运行前提是已链接wslcsdk.lib并完成 COM 初始化与会话创建WslcTagImageOptions tagOptions { 0 }; tagOptions.image docker.io/library/alpine:latest; tagOptions.repo demo/alpine; tagOptions.tag stable; HRESULT hr WslcTagSessionImage(session, tagOptions, NULL); if (FAILED(hr)) { // 处理失败可读取 errorMessage 获取详情 }在完整生命周期中的位置WslcTagSessionImage通常与镜像拉取、列表、推送、删除 API 配合使用。完整的生命周期示例见 end-to-end-example.md其典型顺序为调用WslcInitSessionSettings/WslcCreateSession创建会话调用WslcPullSessionImage拉取基础镜像调用WslcTagSessionImage为镜像添加目标仓库前缀与新标签便于后续推送调用WslcPushSessionImage推送到注册表调用WslcListSessionImages校验结果调用WslcDeleteSessionImage清理不再需要的标签最后WslcTerminateSession/WslcReleaseSession释放资源。错误处理与参数校验源码级在 wslcsdk.cpp 中WslcTagSessionImage的实现按顺序执行如下校验STDAPI WslcTagSessionImage(_In_ WslcSession session, _In_ const WslcTagImageOptions* options, _Outptr_opt_result_z_ PWSTR* errorMessage) try { ErrorInfoWrapper errorInfoWrapper{errorMessage}; auto internalType CheckAndGetInternalType(session); RETURN_HR_IF_NULL(HRESULT_FROM_WIN32(ERROR_INVALID_STATE), internalType-session); RETURN_HR_IF_NULL(E_POINTER, options); RETURN_HR_IF_NULL(E_INVALIDARG, options-image); RETURN_HR_IF_NULL(E_INVALIDARG, options-repo); RETURN_HR_IF_NULL(E_INVALIDARG, options-tag); WSLCCompatTagImageOptions runtimeOptions{}; runtimeOptions.Image options-image; runtimeOptions.Repo options-repo; runtimeOptions.Tag options-tag; return errorInfoWrapper.CaptureResult(internalType-session-TagImage(runtimeOptions)); } CATCH_RETURN();校验顺序与返回码对应关系如下条件返回码含义会话无效或未启动HRESULT_FROM_WIN32(ERROR_INVALID_STATE)底层session为空options为NULLE_POINTER选项指针为空options-image为NULLE_INVALIDARG源镜像未指定options-repo为NULLE_INVALIDARG目标仓库未指定options-tag为NULLE_INVALIDARG目标标签未指定校验通过后函数将公开结构体转换为内部运行时结构体WSLCCompatTagImageOptions再委托给会话对象的TagImage方法执行实际标记操作最后通过errorInfoWrapper.CaptureResult把底层错误连同可读消息一并返回给调用方。所有 C 层异常都会由CATCH_RETURN()统一转换为HRESULT避免 C 异常泄漏到 C 调用边界。测试用例佐证上述错误码行为与 WslcSdkTests.cpp 中的TagImage测试方法完全一致WSLC_TEST_METHOD(TagImage) { // Positive: tag an existing image. { WslcTagImageOptions opts{}; opts.image debian:latest; opts.repo debian; opts.tag sdk-test-tag; VERIFY_SUCCEEDED(WslcTagSessionImage(m_defaultSession, opts, nullptr)); // Verify the tag is present. VERIFY_IS_TRUE(HasImage(debian:sdk-test-tag)); // Cleanup: delete the tag. WslcDeleteSessionImage(m_defaultSession, debian:sdk-test-tag, nullptr); } // Negative: null options must fail. VERIFY_ARE_EQUAL(WslcTagSessionImage(m_defaultSession, nullptr, nullptr), E_POINTER); // Negative: null fields must fail. { WslcTagImageOptions opts{}; opts.image nullptr; opts.repo debian; opts.tag test; VERIFY_ARE_EQUAL(WslcTagSessionImage(m_defaultSession, opts, nullptr), E_INVALIDARG); } // ... repo / tag 为 NULL 的用例同理 }测试验证了三个关键事实标记成功后新标签立即在镜像列表中可见HasImage(debian:sdk-test-tag)为真options为NULL返回E_POINTERimage、repo、tag任一字段为NULL均返回E_INVALIDARG。典型实战场景标记后推送镜像WslcTagSessionImage最常见的用途是配合本地注册表完成拉取 → 标记 → 推送。在 WslcSdkTests.cpp 的PushImageToRegistry辅助方法中可以看到完整模式// Tags and pushes an image to a local registry via the SDK APIs. void PushImageToRegistry(const std::string repo, const std::string tag, const std::string registryAddress, const std::string registryAuth) { auto imageName std::format({}:{}, repo, tag); auto registryImage std::format({}/{}:{}, registryAddress, repo, tag); auto registryRepo std::format({}/{}, registryAddress, repo); VERIFY_IS_TRUE(HasImage(imageName)); // Tag the image with the registry address so it can be pushed. WslcTagImageOptions tagOptions{}; tagOptions.image imageName.c_str(); tagOptions.repo registryRepo.c_str(); tagOptions.tag tag.c_str(); VERIFY_SUCCEEDED(WslcTagSessionImage(m_defaultSession, tagOptions, nullptr)); // Ensures the registry-prefixed tag is removed after the push. auto cleanup wil::scope_exit_log(WI_DIAGNOSTICS_INFO, []() { LOG_IF_FAILED(WslcDeleteSessionImage(m_defaultSession, registryImage.c_str(), nullptr)); }); WslcPushImageOptions pushOptions{}; pushOptions.image registryImage.c_str(); pushOptions.registryAuth registryAuth.c_str(); VERIFY_SUCCEEDED(WslcPushSessionImage(m_defaultSession, pushOptions, nullptr)); }这里的关键点本地镜像名为repo:tag如debian:latest要推送到注册表必须先用WslcTagSessionImage生成带注册表地址的镜像名localhost:5000/debian:latest即registryRepo registryAddress/repo否则推送 API 无法定位远端仓库推送完成后立即用WslcDeleteSessionImage删除注册表前缀标签保持本地镜像库干净WslcPushSessionImage需要registryAuth字段提供注册表认证信息如 Docker 的 Base64 认证串参见 wslcpushsessionimage.md。底层调用链从 C API 到 WinRT 封装WslcTagSessionImage并不直接操作镜像存储而是将工作委托给会话对象的TagImage方法。该 API 同时被 WinRT 层复用在 Session.cpp 中WinRT 的Session::TagImage方法在完成空指针检查与EnsureStarted()确保会话已启动后直接调用 C 层WslcTagSessionImagevoid Session::TagImage(winrt::Microsoft::WSL::Containers::TagImageOptions const options) { if (!options) { throw winrt::hresult_error(E_POINTER, LTag image options cannot be null); } EnsureStarted(); wil::unique_cotaskmem_string errorMessage; auto hr WslcTagSessionImage(ToHandle(), GetStructPointer(options), errorMessage.put()); THROW_MSG_IF_FAILED(hr, errorMessage); }由此可以推断出完整的调用链WslcTagSessionImage (C API) └─ session-TagImage(runtimeOptions) // C 内部实现 └─ WinRT Session::TagImage // WinRT 封装可选路径 └─ WslcTagSessionImage // 复用同一 C 入口该函数通过 wslcsdk.def 导出是 wslcsdk.dll 对外公开的稳定 ABI 接口之一同时它也作为 WinRTMicrosoft.WSL.Containers命名空间的底层实现存在选项结构体的 WinRT 版本见 TagImageOptions.cpp。也就是说无论是纯 C 调用方还是 WinRT/C# 调用方最终都收敛到同一个标记实现行为完全一致。常见问题与最佳实践忘记初始化结构体务必用{ 0 }初始化WslcTagImageOptions否则未赋值的字段可能包含垃圾值导致校验行为不可预期。标签命名标签应遵循 OCI/Docker 标签规范字母、数字、_、.、-且以字母或数字开头结尾虽然 SDK 本身依赖底层运行时校验但提前遵循规范可以避免推送阶段失败。标记后验证调用WslcListSessionImages确认新标签出现在镜像列表中测试代码中的HasImage即为此模式。释放错误信息当errorMessage输出非空时使用CoTaskMemFree释放这也是 WslcListSessionImages 等 API 的共同约定。会话生命周期标记操作必须在会话存活期间执行会话终止后句柄失效再次调用会得到ERROR_INVALID_STATE。C 调用方需初始化 COM与 SDK 中其他 API 一致使用前应调用CoInitializeEx结束时CoUninitialize参见 end-to-end-example.md。相关 API 一览WslcTagSessionImage属于图像管理 API 家族完整的成员列表见 image-apis/index.mdAPI功能WslcPullSessionImage从注册表拉取镜像到会话WslcImportSessionImage/WslcImportSessionImageFromFile导入镜像含从文件导入WslcLoadSessionImage/WslcLoadSessionImageFromFile加载镜像含从文件加载WslcListSessionImages列出会话中的镜像WslcTagSessionImage为镜像创建新标签本文主题WslcDeleteSessionImage删除镜像或某个标签WslcPushSessionImage推送镜像到注册表这些 API 共用一个WslcSession会话句柄句柄类型见 handle-types.md构成了 WSL 容器镜像从拉取、标记、推送到清理的完整闭环。结合 end-to-end-example.md 与 WslcSdkTests.cpp 中的测试代码你可以在自己的 C/C 项目中安全地复刻这一工作流。【免费下载链接】WSLWindows Subsystem for Linux项目地址: https://gitcode.com/GitHub_Trending/ws/WSL创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表