)
WSL C API 指南使用 WslcSetContainerSettingsDomainName 配置容器域名WSL Container SDK【免费下载链接】WSLWindows Subsystem for Linux项目地址: https://gitcode.com/GitHub_Trending/ws/WSL导读WslcSetContainerSettingsDomainName是 Windows Subsystem for LinuxWSLContainer SDKWslc中用于为容器配置 DNS 域名的 C 接口。通过该 API开发者可以在创建容器之前将容器加入自定义 DNS 域例如example.internal使容器内domainname命令返回预设的域名满足企业内部 DNS 解析、服务发现与容器网络标识的定制需求。本文将结合 WSL 开源仓库中 Wslc SDK 的源码实现与测试用例从函数签名、调用流程、底层传递链路到实战代码示例完整解析该 API 的使用方法。函数签名与参数说明该 API 的原型声明位于 WSL 仓库的 WslcSDK 公共头文件完整签名如下STDAPI WslcSetContainerSettingsDomainName(_In_ WslcContainerSettings* containerSettings, _In_ PCSTR domainName);参数类型方向说明containerSettingsWslcContainerSettings*in指向待配置的容器设置对象该对象必须已通过WslcInitContainerSettings初始化domainNamePCSTRin以空字符结尾的 ANSI 字符串表示要设置给容器的 DNS 域名例如example.internal函数返回值为HRESULT调用成功时返回S_OK。适用前提与限制本 API 属于 Wslc SDK 的公共接口。根据 wslcsdk.h 文件头部的 PREVIEW NOTICE该 SDK 目前处于预览阶段函数签名与行为在正式发布前可能发生破坏性变更不建议在面向生产的工作负载中依赖其 API 稳定性。代码示例官方 API 参考文档给出的最小调用示例为HRESULT hr WslcSetContainerSettingsDomainName(containerSettings, example.internal);在实际使用中WslcSetContainerSettingsDomainName是可选的容器设置项OPTIONAL CONTAINER SETTINGS必须配合容器设置初始化和容器创建流程一起使用。一个完整的调用链如下WslcContainerSettings containerSettings; WslcContainer container nullptr; HRESULT hr; // 1. 基于镜像初始化容器设置必选 hr WslcInitContainerSettings(debian:latest, containerSettings); if (FAILED(hr)) { /* 处理失败 */ } // 2. 设置容器 DNS 域名可选 hr WslcSetContainerSettingsDomainName(containerSettings, example.internal); if (FAILED(hr)) { /* 处理失败 */ } // 3. 在已创建的会话session中创建容器 hr WslcCreateContainer(session, containerSettings, container, /* errorMessage */ nullptr); if (FAILED(hr)) { /* 处理失败 */ } // 4. 启动容器并运行进程 hr WslcStartContainer(container, WSLC_CONTAINER_START_FLAG_NONE, /* errorMessage */ nullptr); // 5. 使用完毕后释放容器句柄 WslcReleaseContainer(container);注意domainName与容器的 hostname通过 WslcSetContainerSettingsHostName 设置是两个不同的概念——hostname 标识容器本身的名称domainName 则用于标识容器所属的 DNS 域二者组合共同构成容器完整的网络身份。源码实现设置项如何被存储从 SDK 实现来看WslcContainerSettings对调用方是不透明的字节数组_opaque大小为WSLC_CONTAINER_OPTIONS_SIZE即 104 字节SDK 内部通过类型转换访问真正的内部结构。相关内部结构定义在 WslcsdkPrivate.htypedef struct WslcContainerOptionsInternal { PCSTR image; // Image name (repository:tag) PCSTR runtimeName; // Container runtime name (expected to allow DNS resolution between containers) PCSTR HostName; PCSTR DomainName; const WslcContainerPortMapping* ports; uint32_t portsCount; // ... 其他字段 PCSTR networkMode; WslcContainerFlags containerFlags; } WslcContainerOptionsInternal;WslcSetContainerSettingsDomainName的实现位于 wslcsdk.cppSTDAPI WslcSetContainerSettingsDomainName(_In_ WslcContainerSettings* containerSettings, _In_ PCSTR domainName) try { auto internalType CheckAndGetInternalType(containerSettings); internalType-DomainName domainName; return S_OK; } CATCH_RETURN();可以看到该函数的职责非常单纯通过CheckAndGetInternalType把不透明的WslcContainerSettings*转换为内部的WslcContainerOptionsInternal*然后将domainName指针存入DomainName字段并返回S_OK。函数体包裹在try/CATCH_RETURN()宏中意味着若内部类型转换或分配失败会以 HRESULT 错误码的形式返回异常信息这也是 Wslc SDK 中所有设置类 API 的通用模式。作为对比同一源文件中 WslcSetContainerSettingsHostName 的实现 与之结构完全一致仅赋值字段不同。底层传递链路DomainName 如何到达容器运行时设置值并不会在 SDK 层立即生效而是在调用WslcCreateContainer时被打包并传递给 WSL 容器运行时。追踪源码可以发现完整的传递链路SDK 层填充兼容结构在 wslcsdk.cpp 的 WslcCreateContainer 实现 中内部设置被转换为WSLCCompatContainerOptions兼容结构containerOptions.Image internalContainerSettings-image; containerOptions.Name internalContainerSettings-runtimeName; containerOptions.HostName internalContainerSettings-HostName; containerOptions.DomainName internalContainerSettings-DomainName;服务层 IDL 接口定义WSLCCompatContainerOptions在 WSLCCompat.idl 中声明了[unique] LPCSTR DomainName;字段服务层的 wslc.idl 同样包含[unique] LPCSTR DomainName;字段二者共同定义了跨进程SDK 与服务的 COM 接口数据契约。容器会话层落地在 WSLCContainer.cpp 中创建容器请求最终携带域名信息if (containerOptions.DomainName ! nullptr) { request.Domainname containerOptions.DomainName; }注意此处有非空判断只有当调用方确实设置了域名时请求中才会携带该字段。API 兼容层APICompat.cpp 中m_value.DomainName Options.DomainName;完成兼容层内部的赋值确保新老接口的数据可以互通。从源码结构可以推断该域名最终会传递给容器内的 init 进程由容器内部的 Linux 环境配置机制写入domainnameNIS 域名或 DNS 搜索域等网络配置。测试用例验证仓库的 WslcSdkTests.cpp 中提供了名为ContainerDomainName的测试方法从单元与功能两个层面验证该 APIWSLC_TEST_METHOD(ContainerDomainName) { // Unit: setting a domain name succeeds. { WslcContainerSettings containerSettings; VERIFY_SUCCEEDED(WslcInitContainerSettings(debian:latest, containerSettings)); VERIFY_SUCCEEDED(WslcSetContainerSettingsDomainName(containerSettings, my.domain)); } // Functional: container should see the configured domain name. { WslcProcessSettings procSettings; VERIFY_SUCCEEDED(WslcInitProcessSettings(procSettings)); const char* argv[] {/bin/sh, -c, echo $(domainname)}; VERIFY_SUCCEEDED(WslcSetProcessSettingsCmdLine(procSettings, argv, ARRAYSIZE(argv))); WslcContainerSettings containerSettings; VERIFY_SUCCEEDED(WslcInitContainerSettings(debian:latest, containerSettings)); VERIFY_SUCCEEDED(WslcSetContainerSettingsInitProcess(containerSettings, procSettings)); VERIFY_SUCCEEDED(WslcSetContainerSettingsDomainName(containerSettings, test.local)); auto output RunContainerAndCapture(m_defaultSession, containerSettings); VERIFY_ARE_EQUAL(output.stdoutOutput, test.local\n); } }该测试揭示了两个关键点单元层面初始化debian:latest镜像的容器设置后调用WslcSetContainerSettingsDomainName(containerSettings, my.domain)应成功返回VERIFY_SUCCEEDED。功能层面完整走一遍「初始化进程设置 → 设置 init 进程 → 设置域名 → 运行容器并捕获输出」的流程容器内执行echo $(domainname)应输出test.local证明域名配置确实生效于容器内部。RunContainerAndCapture内部会执行创建与启动容器等步骤验证了域名在整个容器生命周期中的传递。WinRT 封装与配套 API对于 C/WinRT 调用方Wslc SDK 还提供了对应的托管式封装。ContainerSettings.cpp 中暴露了DomainName属性hstring ContainerSettings::DomainName() { return winrt::to_hstring(m_domainName); } void ContainerSettings::DomainName(hstring const value) { m_domainName winrt::to_string(value); }并在 应用设置时 调用底层 C APIif (!m_domainName.empty()) { winrt::check_hresult(WslcSetContainerSettingsDomainName(m_containerSettings.get(), m_domainName.c_str())); }对应地在 wslcsdk.idl 中声明为String DomainName;。WinRT 封装会先把hstring转成 UTF-8 字符串且仅当域名非空时才触发底层调用调用结果通过check_hresult抛出异常——这与 C API 直接返回 HRESULT 的错误处理风格形成互补。使用建议与最佳实践结合源码实现与测试用例归纳以下实践要点调用顺序WslcSetContainerSettingsDomainName必须在WslcInitContainerSettings之后、WslcCreateContainer之前调用因为该函数只是修改内存中的设置对象只有创建容器时才会被读取。创建完成后再调用不会影响已创建的容器。字符串生命周期实现中仅保存domainName指针internalType-DomainName domainName并未复制字符串内容。因此调用方必须保证传入的字符串在WslcCreateContainer完成之前一直有效例如使用静态字符串、堆上长期存活的缓冲区或与设置对象生命周期同步的缓冲区。与 HostName 配合域名与主机名WslcSetContainerSettingsHostName应配合使用以构建完整的 FQDN 网络身份测试中 hostname 同样通过echo $(hostname)在容器内验证可见二者是并列的容器标识配置项。错误处理所有 Wslc 调用都应检查 HRESULT。公共头文件中还定义了 WSLC 特有的错误码如WSLC_E_CONTAINER_NOT_FOUND等定义于 wslcsdk.h可用于区分失败原因此外 SDK 还提供WslcGetMissingComponents、WslcGetVersion等函数用于前置检查运行环境是否满足要求。通过domainname命令验证容器启动后可在容器内执行domainname或echo $(domainname)确认域名是否生效这是测试用例采用的验证方式也是最直接的排查手段。总结WslcSetContainerSettingsDomainName是 Wslc SDK 中配置容器 DNS 域名的核心入口其使用模式与同族的WslcSetContainerSettingsHostName、WslcSetContainerSettingsName等可选设置项一致初始化设置 → 链式调用 setter → 创建容器。通过仓库源码可以确认该值经由 SDK 内部结构、兼容层 COM 接口一路传递至容器运行时最终在容器内以domainname形式呈现。配合 Container APIs 总览 中的其他 API开发者可以完整地按需定制 WSL 容器的网络身份与运行行为。【免费下载链接】WSLWindows Subsystem for Linux项目地址: https://gitcode.com/GitHub_Trending/ws/WSL创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考