WSL 容器 API 的 Session APIs 全面指南:用 Wslc 系列函数管理容器会话生命周期
2026/9/11 6:02:17 网站建设 项目流程

WSL 容器 API 的 Session APIs 全面指南:用 Wslc 系列函数管理容器会话生命周期

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

本指南以 WSL 容器 API(WSL Container API)C 语言参考中的 Session APIs 为绝对核心,完整讲解从会话初始化、资源配额设置、会话创建、终止监听、崩溃转储订阅到会话清理的全部 14 个 API 函数。你将掌握如何在 Windows 上以编程方式创建、配置、监控和销毁一个容器会话,并深入理解WslcSessionSettings不透明结构的内部布局与wslcsdk实现层的默认值行为。文章末尾还给出可编译运行的完整生命周期示例,帮你把每个 API 串成一条可落地的调用链。

适用前提:本 API 属于 Windows Subsystem for Linux(WSL)的容器 SDK,当前处于Preview 阶段(见 C API 参考入口),函数签名与行为可能在后续版本中无通知变更,请勿在正式生产负载中依赖其稳定性。编译时需要wslcsdk.h头文件与wslcsdk.lib/wslcsdk.dll库(头文件声明见 wslcsdk.h,导出符号见 wslcsdk.def)。


一、Session APIs 全貌:14 个函数的职责分组

会话(Session)是 WSL 容器 API 中最顶层的资源抽象:一个会话对应一台面向 Linux 容器负载的虚拟机运行环境,容器(Container)创建在会话之内,进程(Process)又运行在容器之内。Session APIs 负责回答"如何把这样一台虚拟机拉起来、配好资源、监视其存亡、最后干净地关掉"。

Session APIs 索引 将全部 14 个函数分为五类:

类别函数职责
会话设置初始化WslcInitSessionSettings创建并填充WslcSessionSettings结构(必调,第一步)
会话设置微调WslcSetSessionSettingsCpuCount设置 CPU 核数
WslcSetSessionSettingsMemory设置内存上限(MB)
WslcSetSessionSettingsTimeout设置引导超时(毫秒)
WslcSetSessionSettingsVhd设置 VHD 存储需求
WslcSetSessionSettingsFeatureFlags设置会话特性开关(如 GPU)
会话生命周期WslcCreateSession基于设置创建会话,返回WslcSession句柄
WslcTerminateSession终止会话
WslcReleaseSession释放会话句柄
会话状态监控WslcGetSessionTerminationEvent获取会话终止事件句柄(HANDLE
WslcGetSessionTerminationReason查询终止原因
崩溃转储订阅WslcRegisterSessionCrashDumpCallback注册崩溃转储回调
WslcReleaseCrashDumpSubscription取消崩溃转储订阅
会话内认证WslcSessionAuthenticate向会话内服务完成身份认证,获取身份令牌

典型调用顺序:WslcInitSessionSettings→(可选)各WslcSetSessionSettings*WslcCreateSession→ 使用会话创建容器/拉取镜像 → 监控终止事件 →WslcTerminateSessionWslcReleaseSession


二、会话设置初始化:WslcInitSessionSettings

STDAPI WslcInitSessionSettings(_In_ PCWSTR name, _In_ PCWSTR storagePath, _Out_ WslcSessionSettings* sessionSettings);
参数类型方向说明
namePCWSTRin待创建会话的名称
storagePathPCWSTRin会话存储写入路径;路径不存在时会自动创建
sessionSettingsWslcSessionSettings*out接收设置的指针

返回值:HRESULT

该函数是会话编程的强制入口:必须先调用它拿到一个合法的WslcSessionSettings,之后才能调用任何WslcSetSessionSettings*系列函数或WslcCreateSession。若直接传入未初始化的栈结构,底层实现会因内部类型指针无效而失败。

2.1 会话名称的机器级可见性与安全约束

文档特别强调了两点约束(见 WslcInitSessionSettings):

  • 会话名是机器级键:会话名既是显示名,也是全机器范围内标识会话的键。若同名会话已存在,创建将失败并返回ERROR_ALREADY_EXISTS
  • 全机器可见的信息:以下信息对机器上所有用户可见——会话名称、创建会话的用户的 SID、创建会话的进程的 PID。
  • 安全警告:不要在会话名中放置凭据或其他敏感信息。
WslcSessionSettings sessionSettings; HRESULT hr = WslcInitSessionSettings( L"demo-session", L"C:\\WSLC\\demo-session", &sessionSettings);

2.2 实现层做了什么:不透明结构与默认值

WslcSessionSettings在公开头文件中被定义为不透明(opaque)结构(见 structures/wslcsessionsettings.md 与 wslcsdk.h):

#define WSLC_SESSION_OPTIONS_SIZE 72 #define WSLC_SESSION_OPTIONS_ALIGNMENT 8 typedef struct WslcSessionSettings { __declspec(align(WSLC_SESSION_OPTIONS_ALIGNMENT)) BYTE _opaque[WSLC_SESSION_OPTIONS_SIZE]; } WslcSessionSettings;

从 wslcsdk.cpp 的实现可见,WslcInitSessionSettings在内部将displayNamestoragePath写入不透明缓冲区,并一次性灌入四个默认值:

内部字段默认值来源
cpuCount2Defaults.h
memoryMb2000(约 2 GB)Defaults.h
timeoutMS300000(5 分钟,受HVSOCKET_CONNECT_TIMEOUT_MAX约束)Defaults.h
vhdRequirements.sizeBytes32ULL * 1024 * 1024 * 1024(32 GB)Defaults.h

这意味着即使你只调用WslcInitSessionSettings不做任何微调,会话也已具备 2 核 CPU、2 GB 内存、5 分钟引导超时与 32 GB 存储的默认配额,无需关心底层细节。


三、会话资源配置:五个 Set 系列函数

所有WslcSetSessionSettings*函数都遵循同一约定:第一个参数是被修改的WslcSessionSettings*,返回HRESULT,且必须在WslcInitSessionSettings之后、WslcCreateSession之前调用。

3.1 CPU 核数:WslcSetSessionSettingsCpuCount

STDAPI WslcSetSessionSettingsCpuCount(_In_ WslcSessionSettings* sessionSettings, _In_ uint32_t cpuCount);
参数类型方向
sessionSettingsWslcSessionSettings*in
cpuCountuint32_tin
HRESULT hr = WslcSetSessionSettingsCpuCount(&sessionSettings, (uint32_t)4);

实现细节(wslcsdk.cpp):当传入cpuCount非 0 时写入选定值;传入 0 则回落为默认值s_DefaultCPUCount(2)。内存与超时函数遵循同样的"0 值回落默认"语义(见下文),因此 0 在这里不是一个合法的"零核"配置,而是"使用默认值"的约定。

3.2 内存上限:WslcSetSessionSettingsMemory

STDAPI WslcSetSessionSettingsMemory(_In_ WslcSessionSettings* sessionSettings, _In_ uint32_t memoryMB);

单位是MB。示例将内存设置为 4 GB:

HRESULT hr = WslcSetSessionSettingsMemory(&sessionSettings, (uint32_t)4096);

实现(wslcsdk.cpp):memoryMB非 0 则写入,为 0 则回落s_DefaultMemoryMB(2000 MB)。

3.3 引导超时:WslcSetSessionSettingsTimeout

STDAPI WslcSetSessionSettingsTimeout(_In_ WslcSessionSettings* sessionSettings, _In_ uint32_t timeoutMS);

单位是毫秒。示例将引导超时设为 2 分钟:

HRESULT hr = WslcSetSessionSettingsTimeout(&sessionSettings, (uint32_t)120000);

实现(wslcsdk.cpp):timeoutMS非 0 则写入,为 0 则回落s_DefaultBootTimeout(300000 ms = 5 分钟)。该超时最终作用于底层 hvsocket 引导连接阶段,Defaults.h注释表明其上限受HVSOCKET_CONNECT_TIMEOUT_MAX约束,超时对慢速磁盘上的首次启动尤为重要。

3.4 VHD 存储需求:WslcSetSessionSettingsVhd

STDAPI WslcSetSessionSettingsVhd(_In_ WslcSessionSettings* sessionSettings, _In_opt_ const WslcVhdRequirements* vhdRequirements);
参数类型方向
sessionSettingsWslcSessionSettings*in
vhdRequirementsconst WslcVhdRequirements*in,可选

传入NULL表示不使用自定义 VHD 需求。WslcVhdRequirements结构定义(见 structures/wslcvhdrequirements.md 与 wslcsdk.h):

typedef struct WslcVhdRequirements { _In_z_ PCSTR name; // 被 WslcSetSessionSettingsVhd 忽略 _In_ uint64_t sizeBytes; // 期望大小(用于创建/扩容) _In_ WslcVhdType type; // WSLC_VHD_TYPE_DYNAMIC 或 WSLC_VHD_TYPE_FIXED _In_ WslcVhdRequirementsFlags flags; // WSLC_VHD_REQ_FLAG_NONE / WSLC_VHD_REQ_FLAG_OWNER _In_ uint32_t uid; // 仅当 (flags & WSLC_VHD_REQ_FLAG_OWNER) 时生效 _In_ uint32_t gid; // 仅当 (flags & WSLC_VHD_REQ_FLAG_OWNER) 时生效 } WslcVhdRequirements;

头文件注释明确了两条关键语义(wslcsdk.h):

  • name字段被WslcSetSessionSettingsVhd忽略
  • type之后的字段(flags/uid/gid)只被WslcCreateSessionVhdVolume采纳;
  • WslcSetSessionSettingsVhd遇到非NONE的 flags 会返回E_INVALIDARG(对应实现见 wslcsdk.cpp 之后的校验分支);
  • WSLC_VHD_TYPE_FIXED只被WslcCreateSessionVhdVolume尊重——在会话设置阶段请使用默认的WSLC_VHD_TYPE_DYNAMIC

也就是说,在设置阶段WslcSetSessionSettingsVhd只关心sizeBytes,用于声明会话磁盘的默认大小(默认 32 GB,见 Defaults.h);完整的 VHD 创建语义(固定/动态、属主 uid/gid)在 Storage APIs 的WslcCreateSessionVhdVolume中体现。示例(将默认存储扩容到 64 GB):

WslcVhdRequirements vhdRequirements = { 0 }; vhdRequirements.name = "ignored-by-WslcSetSessionSettingsVhd"; vhdRequirements.sizeBytes = (uint64_t)64 * 1024 * 1024 * 1024; vhdRequirements.type = WSLC_VHD_TYPE_DYNAMIC; vhdRequirements.flags = WSLC_VHD_REQ_FLAG_NONE; vhdRequirements.uid = (uint32_t)0; vhdRequirements.gid = (uint32_t)0; HRESULT hr = WslcSetSessionSettingsVhd(&sessionSettings, &vhdRequirements);

3.5 特性开关:WslcSetSessionSettingsFeatureFlags

STDAPI WslcSetSessionSettingsFeatureFlags(_In_ WslcSessionSettings* sessionSettings, _In_ WslcSessionFeatureFlags flags);

WslcSessionFeatureFlags枚举(见 enumerations/wslcsessionfeatureflags.md 与 wslcsdk.h):

枚举值含义
WSLC_SESSION_FEATURE_FLAG_NONE0x00000000无特性
WSLC_SESSION_FEATURE_FLAG_ENABLE_GPU0x00000004启用 GPU 加速

启用 GPU 加速的示例:

HRESULT hr = WslcSetSessionSettingsFeatureFlags( &sessionSettings, WSLC_SESSION_FEATURE_FLAG_ENABLE_GPU);

需要说明的是:会话创建时,SDK 实现还会无条件叠加两个内部特性——WslcFeatureFlagsVirtioFs(virtio-fs 文件系统)与WslcFeatureFlagsDnsTunneling(DNS 隧道),见 wslcsdk.cpp。因此该 API 暴露的是用户可控制的特性位,与实现内部固定启用的特性是叠加关系。


四、创建会话:WslcCreateSession

STDAPI WslcCreateSession(_In_ WslcSessionSettings* sessionSettings, _Out_ WslcSession* session, _Outptr_opt_result_z_ PWSTR* errorMessage);
参数类型方向说明
sessionSettingsWslcSessionSettings*in已初始化并配置好的设置
sessionWslcSession*out接收新会话句柄
errorMessagePWSTR*out,可选失败时返回人类可读错误信息

返回值:HRESULT

WslcSession session = NULL; HRESULT hr = WslcCreateSession(&sessionSettings, &session, NULL);

4.1 实现层的调用链

从 wslcsdk.cpp 可以看到WslcCreateSession的完整内部流程:

  1. 通过CheckAndGetInternalType取出WslcSessionSettings内部字段;
  2. 创建兼容会话管理器IWSLCCompatSessionManager
  3. 将公开字段映射为WSLCCompatSessionSettings运行时设置——MaximumStorageSizeMbvhdRequirements.sizeBytes / 1MB计算得出、CpuCountMemoryMbBootTimeoutMsNetworkingMode = WSLCNetworkingModeConsomme(Consomme 网络栈)、FeatureFlagsConvertFlags转换;
  4. 叠加 VirtioFs 与 DNS Tunneling 两个内部特性位;
  5. 调用sessionManager->CreateSession(...)真正拉起会话;
  6. 成功后通过ConfigureForCOMImpersonation配置 COM 模拟身份(服务端进程管控的一部分),并将句柄返回给调用者。

会话句柄本身由DECLARE_HANDLE(WslcSession)声明(wslcsdk.h),对调用方是不透明句柄,只能传给其他 Wslc API 使用。若CreateSession失败,错误信息会写入可选的errorMessage参数,调用方需用CoTaskMemFree释放。

4.2 先决条件检查

在调用WslcCreateSession之前,官方端到端示例(end-to-end-example.md)还建议先通过WslcGetMissingComponents检查平台组件是否就绪,缺失时提示运行wsl --install

WslcComponentFlags missing = WSLC_COMPONENT_FLAG_NONE; hr = WslcGetMissingComponents(&missing); if (FAILED(hr) || missing != WSLC_COMPONENT_FLAG_NONE) { printf("WSL components are missing. Run: wsl --install\n"); CoUninitialize(); return 1; }

五、监控会话终止:事件 + 原因查询

5.1 获取终止事件:WslcGetSessionTerminationEvent

STDAPI WslcGetSessionTerminationEvent(_In_ WslcSession session, _Out_ HANDLE* terminationEvent);
参数类型方向
sessionWslcSessionin
terminationEventHANDLE*out

返回的HANDLE是标准 Windows 事件内核对象,可直接用于WaitForSingleObject/WaitForMultipleObjects/SetThreadpoolWait等任意等待机制:

HANDLE terminationEvent = NULL; HRESULT hr = WslcGetSessionTerminationEvent(session, &terminationEvent); if (SUCCEEDED(hr)) { WaitForSingleObject(terminationEvent, 1000); }

5.2 查询终止原因:WslcGetSessionTerminationReason

STDAPI WslcGetSessionTerminationReason(_In_ WslcSession session, _Out_ WslcSessionTerminationReason* reason);
参数类型方向
sessionWslcSessionin
reasonWslcSessionTerminationReason*out

WslcSessionTerminationReason枚举(见 enumerations/wslcsessionterminationreason.md 与 wslcsdk.h):

枚举值含义
WSLC_SESSION_TERMINATION_REASON_UNKNOWN0未知原因
WSLC_SESSION_TERMINATION_REASON_SHUTDOWN1正常关闭
WSLC_SESSION_TERMINATION_REASON_CRASHED2崩溃终止
WslcSessionTerminationReason reason = WSLC_SESSION_TERMINATION_REASON_UNKNOWN; HRESULT hr = WslcGetSessionTerminationReason(session, &reason);

5.3 源码证据:WinRT 层如何组合使用这两个 API

在 SDK 的 WinRT 投影实现 winrt/Session.cpp 中,Start()展示了标准的监控接线方式:

  1. WslcCreateSession创建会话;
  2. WslcGetSessionTerminationEvent取出终止事件;
  3. CreateThreadpoolWait+SetThreadpoolWait把终止事件挂到线程池等待上;
  4. 当线程池回调OnTerminated触发时(Session.cpp),回调内部调用WslcGetSessionTerminationReason查询终止原因并向外抛出Terminated事件。

可见,"事件句柄 + 终止原因查询"这一对 API 正是上层封装事件模型的底层基石:事件解决"什么时候终止"的同步问题,原因枚举解决"为什么终止"的诊断问题。


六、崩溃转储订阅:回调注册与释放

6.1 回调类型与信息结构

回调类型定义(见 callback-types/wslcsessioncrashdumpcallback.md):

typedef __callback void(CALLBACK* WslcSessionCrashDumpCallback)(_In_ const WslcSessionCrashDumpInfo* info, _In_opt_ PVOID context);

回调携带的WslcSessionCrashDumpInfo结构(见 structures/wslcsessioncrashdumpinfo.md 与 wslcsdk.h):

字段类型含义
dumpPathPCWSTR转储文件路径(宽字符)
processNamePCSTR崩溃进程名(窄字符)
piduint32_t崩溃进程 PID
signaluint32_t触发崩溃的信号
timestampuint64_t时间戳

6.2 注册回调:WslcRegisterSessionCrashDumpCallback

STDAPI WslcRegisterSessionCrashDumpCallback( _In_ WslcSession session, _In_ WslcSessionCrashDumpCallback crashDumpCallback, _In_opt_ PVOID crashDumpContext, _Out_ WslcCrashDumpSubscription* subscription, _Outptr_opt_result_z_ PWSTR* errorMessage);
参数类型方向
sessionWslcSessionin
crashDumpCallbackWslcSessionCrashDumpCallbackin
crashDumpContextPVOIDin,可选
subscriptionWslcCrashDumpSubscription*out
errorMessagePWSTR*out,可选

WslcCrashDumpSubscription是不透明句柄,持有它就等于持有注册的存活期(见 wslcsdk.h);同一会话可注册多个订阅。头文件注释还强调该回调对任何持有活动会话的调用者都可用(即不限于创建者),便于独立监控进程挂接。

void CALLBACK OnCrashDump(const WslcSessionCrashDumpInfo* info, PVOID context) { UNREFERENCED_PARAMETER(context); wprintf(L"dump=%ls\n", info->dumpPath); } WslcCrashDumpSubscription subscription = NULL; HRESULT hr = WslcRegisterSessionCrashDumpCallback( session, OnCrashDump, NULL, &subscription, NULL);

6.3 释放订阅:WslcReleaseCrashDumpSubscription

STDAPI WslcReleaseCrashDumpSubscription(_In_ WslcCrashDumpSubscription subscription);
HRESULT hr = WslcReleaseCrashDumpSubscription(subscription); subscription = NULL;

6.4 源码证据:WinRT 层回调适配

WinRT 投影 Session.cpp 中的OnCrashDump展示了回调的典型消费方式:把 C 回调收到的WslcSessionCrashDumpInfo包装成ProcessCrashInformation托管对象,再以事件形式抛给上层应用;而Session::Close对应的析构流程会释放m_crashDumpSubscription。这印证了"注册回调 → 收到信息 → 释放订阅"的完整闭环。


七、会话清理与收尾:Terminate 与 Release

7.1 终止会话:WslcTerminateSession

STDAPI WslcTerminateSession(_In_ WslcSession session);
HRESULT hr = WslcTerminateSession(session);

实现(wslcsdk.cpp):若句柄对应的内部会话不存在,返回HRESULT_FROM_WIN32(ERROR_INVALID_STATE);否则调用session->Terminate()。这是会话的主动关闭路径,会触发终止事件置位,使等待在WslcGetSessionTerminationEvent句柄上的代码得以唤醒。

7.2 释放句柄:WslcReleaseSession

STDAPI WslcReleaseSession(_In_ WslcSession session);
HRESULT hr = WslcReleaseSession(session); session = NULL;

TerminateRelease的分工:WslcTerminateSession负责让虚拟机停止运行WslcReleaseSession负责释放本地句柄引用。官方示例的收尾总是成对出现:先WslcTerminateSession(session),再WslcReleaseSession(session)(见 end-to-end-example.md)。


八、会话内认证:WslcSessionAuthenticate

STDAPI WslcSessionAuthenticate( _In_ WslcSession session, _In_z_ PCSTR serverAddress, _In_z_ PCSTR username, _In_z_ PCSTR password, _Outptr_result_z_ PSTR* identityToken, _Outptr_opt_result_z_ PWSTR* errorMessage);
参数类型方向说明
sessionWslcSessionin目标会话
serverAddressPCSTRin服务器地址(如127.0.0.1:5000
usernamePCSTRin用户名
passwordPCSTRin密码
identityTokenPSTR*out返回的身份令牌
errorMessagePWSTR*out,可选错误信息

内存约定(头文件注释明确):identityTokenCoTaskMemAlloc分配,必须用CoTaskMemFree释放。

PSTR identityToken = NULL; HRESULT hr = WslcSessionAuthenticate( session, "127.0.0.1:5000", "user", "password", &identityToken, NULL); if (SUCCEEDED(hr)) { printf("token=%s\n", identityToken); CoTaskMemFree(identityToken); }

该 API 用于在创建会话后,与会话内暴露的服务(例如镜像注册表服务)建立身份,获取后续操作所需的令牌。注意其地址、用户名、密码均为窄字符(PCSTR)而错误信息为宽字符(PWSTR),与WslcCreateSession的错误信息类型保持一致。


九、端到端实战:从初始化到清理的完整生命周期

把上面的 API 串起来,就是一个可编译运行的完整生命周期程序(改编自官方 end-to-end-example.md,下面对其做逐步注解)。前置条件:CoInitializeEx(nullptr, COINIT_MULTITHREADED)初始化 COM,链接ole32.libwslcsdk.lib

#include <winsock2.h> #include <windows.h> #include <stdio.h> #include <objbase.h> #include <filesystem> #include "wslcsdk.h" #pragma comment(lib, "ole32.lib") #pragma comment(lib, "wslcsdk.lib") int main() { // Initialize COM CoInitializeEx(nullptr, COINIT_MULTITHREADED); HRESULT hr; PWSTR error = nullptr; // 0. Check prerequisites(先决条件检查,组件缺失时提示 wsl --install) WslcComponentFlags missing = WSLC_COMPONENT_FLAG_NONE; hr = WslcGetMissingComponents(&missing); if (FAILED(hr) || missing != WSLC_COMPONENT_FLAG_NONE) { printf("WSL components are missing. Run: wsl --install\n"); CoUninitialize(); return 1; } WslcVersion ver = {}; WslcGetVersion(&ver); printf("WSL version: %u.%u.%u\n", ver.major, ver.minor, ver.revision); // 1. 初始化并创建会话(本指南核心:Session APIs) std::filesystem::path storagePath = std::filesystem::current_path(); WslcSessionSettings sessionSettings; hr = WslcInitSessionSettings(L"MyApp", storagePath.c_str(), &sessionSettings); if (FAILED(hr)) return 1; // 可选:自定义资源配额 WslcSetSessionSettingsCpuCount(&sessionSettings, 4); WslcSetSessionSettingsMemory(&sessionSettings, 4096); WslcSetSessionSettingsTimeout(&sessionSettings, 120000); WslcSession session = nullptr; hr = WslcCreateSession(&sessionSettings, &session, &error); if (FAILED(hr)) { wprintf(L"Session creation failed: %s\n", error ? error : L"unknown"); CoTaskMemFree(error); CoUninitialize(); return 1; } // 2. 拉取镜像(Image APIs) WslcPullImageOptions pullOpts = {}; pullOpts.uri = "docker.io/library/alpine:latest"; hr = WslcPullSessionImage(session, &pullOpts, &error); if (FAILED(hr)) { wprintf(L"Pull failed: %s\n", error ? error : L"unknown"); CoTaskMemFree(error); WslcTerminateSession(session); WslcReleaseSession(session); CoUninitialize(); return 1; } // 3. 配置 init 进程(Process APIs) WslcProcessSettings initProcSettings; WslcInitProcessSettings(&initProcSettings); PCSTR argv[] = { "/bin/echo", "Hello from WSL Container!" }; WslcSetProcessSettingsCmdLine(&initProcSettings, argv, 2); // 4. 配置并创建容器(Container APIs) WslcContainerSettings containerSettings; WslcInitContainerSettings("alpine:latest", &containerSettings); WslcSetContainerSettingsName(&containerSettings, "hello-container"); WslcSetContainerSettingsInitProcess(&containerSettings, &initProcSettings); WslcContainer container = nullptr; hr = WslcCreateContainer(session, &containerSettings, &container, &error); if (FAILED(hr)) { wprintf(L"Container creation failed: %s\n", error ? error : L"unknown"); CoTaskMemFree(error); WslcTerminateSession(session); WslcReleaseSession(session); CoUninitialize(); return 1; } // 5. 启动容器 hr = WslcStartContainer(container, WSLC_CONTAINER_START_FLAG_NONE, &error); if (FAILED(hr)) { wprintf(L"Start failed: %s\n", error ? error : L"unknown"); CoTaskMemFree(error); WslcDeleteContainer(container, WSLC_DELETE_CONTAINER_FLAG_FORCE, nullptr); WslcReleaseContainer(container); WslcTerminateSession(session); WslcReleaseSession(session); CoUninitialize(); return 1; } // 6. 等待 init 进程退出 WslcProcess initProc = nullptr; hr = WslcGetContainerInitProcess(container, &initProc); if (SUCCEEDED(hr)) { HANDLE exitEvent = nullptr; if (SUCCEEDED(WslcGetProcessExitEvent(initProc, &exitEvent))) { WaitForSingleObject(exitEvent, 30000); // 30 秒超时 } INT32 exitCode = 0; if (SUCCEEDED(WslcGetProcessExitCode(initProc, &exitCode))) { printf("Process exited with code: %d\n", exitCode); } WslcReleaseProcess(initProc); } // 7. 清理:停容器、删容器、终止并释放会话 WslcContainerState containerState = WSLC_CONTAINER_STATE_INVALID; if (SUCCEEDED(WslcGetContainerState(container, &containerState)) && containerState == WSLC_CONTAINER_STATE_RUNNING) { WslcStopContainer(container, WSLC_SIGNAL_SIGTERM, 10, nullptr); } WslcDeleteContainer(container, WSLC_DELETE_CONTAINER_FLAG_NONE, nullptr); WslcReleaseContainer(container); WslcTerminateSession(session); WslcReleaseSession(session); CoUninitialize(); return 0; }

生命周期要点回顾

  1. 初始化WslcInitSessionSettings是唯一合法起点,同时写入默认配额;
  2. 配置:各WslcSetSessionSettings*按需覆盖默认值(传 0 回落默认);
  3. 创建WslcCreateSession拉起虚拟机并返回句柄,失败时检查errorMessage
  4. 使用:在会话内进行镜像、容器、进程操作(分属 Image/Container/Process APIs);
  5. 监控(可选)WslcGetSessionTerminationEvent+WslcGetSessionTerminationReason感知退出,WslcRegisterSessionCrashDumpCallback收集崩溃转储;
  6. 清理:先WslcTerminateSessionWslcReleaseSession,顺序不可颠倒,否则句柄泄漏或出现无效状态。

十、常见错误与排查提示

Session APIs 的所有函数均返回HRESULT,通用的 Windows HRESULT(如E_POINTERE_INVALIDARGERROR_ALREADY_EXISTSERROR_INVALID_STATE)之外,还可能返回 WSL 容器专属错误码(完整列表见 error-codes.md),其中与会话场景最相关的是:

错误码十六进制值场景
WSLC_E_SESSION_RESERVED0x80040607会话名被系统保留
WSLC_E_INVALID_SESSION_NAME0x80040608会话名不合法
WSLC_E_SESSION_NOT_FOUND0x8004060F会话不存在
WSLC_E_VM_NOT_RUNNING0x80040610虚拟机未运行(如尝试在已终止会话上操作)
WSLC_E_SDK_UPDATE_NEEDED0x8004060B主机 WSL 组件与 SDK 版本不匹配

排查建议:

  • 创建失败:优先检查WslcGetMissingComponents返回值与errorMessage;确认会话名在机器上唯一且不含敏感信息;
  • 配额未生效:确认传入值非 0(0 会回落默认值),且所有WslcSetSessionSettings*都在WslcCreateSession之前调用;
  • 终止监听失效:确认先WslcGetSessionTerminationEvent再开始等待,且WslcTerminateSession或崩溃路径确实触发;
  • 内存泄漏errorMessageidentityToken均需CoTaskMemFree;会话句柄必须WslcReleaseSession,崩溃订阅必须WslcReleaseCrashDumpSubscription

延伸阅读

  • C API 参考总入口:结构、枚举、回调类型与全部 API 分组
  • Structures 参考:WslcSessionSettingsWslcVhdRequirementsWslcSessionCrashDumpInfo
  • Enumerations 参考:特性标志、终止原因、VHD 类型等枚举全集
  • Error Codes:全部 WSL 容器专属错误码
  • End-to-End Example:官方完整生命周期示例
  • SDK 头文件:所有公开 API 声明与头文件注释
  • SDK 实现:WslcInitSessionSettings/WslcCreateSession/WslcTerminateSession等核心实现
  • 默认值定义:CPU、内存、超时、存储的默认配额
  • WinRT 投影示例:终止事件与崩溃回调在高层 API 中的消费方式

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

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

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

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

立即咨询