WSLC SDK 安装进度回调 WslcInstallCallback 详解:WSL 组件安装的进度上报协议

发布时间:2026/9/10 3:25:54
WSLC SDK 安装进度回调 WslcInstallCallback 详解:WSL 组件安装的进度上报协议 WSLC SDK 安装进度回调 WslcInstallCallback 详解WSL 组件安装的进度上报协议【免费下载链接】WSLWindows Subsystem for Linux项目地址: https://gitcode.com/GitHub_Trending/ws/WSLWslcInstallCallback 是 Windows Subsystem for LinuxWSLWSLC SDKC API中用于上报组件安装进度的回调类型由WslcInstallWithDependencies在安装虚拟机平台Virtual Machine Platform、WSL 运行时包等系统组件时反复调用是开发者构建安装引导界面、进度条与失败恢复逻辑的核心接口。读完本文你将掌握该回调的完整签名与参数语义、各组件进度模型差异以及如何在 C/C 与 WinRT 应用中正确注册并消费安装进度事件。回调类型定位WSLC 安装流程中的进度通道在 WSLCWSL ContainersSDK 的 C API 体系中组件安装由 WslcInstallWithDependencies 驱动而本回调类型正是该函数接受的两个可选参数之一另一个是context。SDK 的头文件位于 wslcsdk.h与它并列的还有会话崩溃转储、标准 I/O、进程退出、容器镜像下载等回调完整清单见 Callback Types 索引。typedef __callback void(CALLBACK* WslcInstallCallback)( _In_ WslcComponentFlags component, _In_ uint32_t progressSteps, _In_ uint32_t totalSteps, _In_opt_ PVOID context);该回调由 SDK 内部安装逻辑调用由应用程序实现并提供给 SDK属于典型的“回调callback”方向安装引擎每完成一个进度步进就通过该函数通知调用方。参数详解ParameterType含义componentWslcComponentFlags当前进度事件所属的组件标识正在安装的子系统组件progressStepsuint32_t当前组件已完成的进度步数从 0 开始递增totalStepsuint32_t当前组件安装所需的总步数用于计算完成比例progressSteps / totalStepscontextPVOID可选。调用方自定义上下文指针原样透传给回调通常用于携带窗口句柄、进度条对象或状态结构体__callback与CALLBACK均展开为__stdcall调用约定_In_/_In_opt_是 SAL 注解分别表示“必填输入”与“可选输入”。回调本身位于进程内同步执行详见下文实现原理因此在回调内部应避免执行耗时操作或可能阻塞安装流程的调用。component 参数安装的是哪个组件component的类型为 WslcComponentFlags在 wslcsdk.h 中定义为位标志枚举支持按位或组合其取值决定了回调语义标志值含义WSLC_COMPONENT_FLAG_NONE0无组件WSLC_COMPONENT_FLAG_VIRTUAL_MACHINE_PLATFORM1“虚拟机平台”可选功能提供的服务其他可选功能也可能提供安装此组件需要重启系统WSLC_COMPONENT_FLAG_WSL_PACKAGE2提供 WSLC 支持能力的 WSL 运行时包WSLC_COMPONENT_FLAG_SDK_NEEDS_UPDATE4表示 WSLC SDK 自身需要更新该标志不会出现在安装回调中见下文SDK 为该枚举定义了DEFINE_ENUM_FLAG_OPERATORS(WslcComponentFlags)因此可以直接使用WI_IsFlagSet、WI_SetFlag等 WIL 标志位辅助宏对返回值进行测试。回调中应当以component区分当前进度属于哪个子流程从而在 UI 上展示不同的文案例如“正在启用虚拟机平台”“正在安装 WSL 运行时包”。进度模型不同组件使用不同的步进刻度progressSteps与totalSteps的组合构成一个简单的“已完成/总量”进度模型但不同组件的刻度并不一致这一点从 wslcsdk.cpp 的实现中可以精确确认虚拟机平台WSLC_COMPONENT_FLAG_VIRTUAL_MACHINE_PLATFORM安装开始前回调一次(component, 0, 1, context)安装完成后回调一次(component, 1, 1, context)。即该组件只有两个进度点0/1 表示进行中1/1 表示完成UI 上可显示为不确定进度条或 0%/100% 两态。WSL 运行时包WSLC_COMPONENT_FLAG_WSL_PACKAGE通过 Windows Update 流程安装SDK 将内部更新进度归一化为0到100的刻度即回调序列为(component, 0, 100)起步、(component, 100, 100)收尾中间按更新引擎上报的实际进度递增。因此回调实现中应始终按totalSteps动态计算百分比progressSteps * 100 / totalSteps而不能硬编码 0~100 或 0/1 假设——两种组件并存时进度模型天然不同。context 参数携带调用方状态context是调用WslcInstallWithDependencies时传入的任意指针SDK 在每次回调时原样回传不会解释其内容。典型用法是传入指向进度条控件、窗口句柄或状态结构的指针避免使用全局变量typedef struct InstallUiState { HWND hwndProgress; int lastPercent; } InstallUiState; void CALLBACK OnInstallProgress( WslcComponentFlags component, uint32_t progressSteps, uint32_t totalSteps, PVOID context) { InstallUiState* state (InstallUiState*)context; int percent (int)((uint64_t)progressSteps * 100 / totalSteps); if (percent ! state-lastPercent) { state-lastPercent percent; // 更新 UISetProgress(percent)并根据 component 切换提示文案 } }如果无需携带状态传NULL并在回调中忽略该参数即可UNREFERENCED_PARAMETER(context);。与 WslcInstallWithDependencies 的完整配合示例SDK 文档在 wslcinstallwithdependencies.md 中给出了可直接编译运行的完整示例完整继承如下void CALLBACK OnInstallProgress( WslcComponentFlags component, uint32_t progressSteps, uint32_t totalSteps, PVOID context) { UNREFERENCED_PARAMETER(context); printf(component%u %u/%u\n, (unsigned)component, progressSteps, totalSteps); } HRESULT hr WslcInstallWithDependencies(OnInstallProgress, NULL);需要说明的是SDK 头文件中该函数的完整声明还包含components与options两个前置参数见 wslcsdk.hSTDAPI WslcInstallWithDependencies( _In_ WslcComponentFlags components, _In_ WslcInstallOptions options, _In_opt_ WslcInstallCallback progressCallback, _In_opt_ PVOID context);其中options取 WslcInstallOptions 枚举WSLC_INSTALL_OPTION_NONE 0为普通安装WSLC_INSTALL_OPTION_REPAIR 1允许重新安装已存在的组件修复模式。安装前的必要准备回调只会针对本次调用实际安装的组件触发。因此标准的调用流程是先用WslcGetMissingComponents查询缺失组件再据此决定安装参数参见 wslcgetmissingcomponents.md 与 端到端示例WslcComponentFlags missing WSLC_COMPONENT_FLAG_NONE; HRESULT hr WslcGetMissingComponents(missing); if (FAILED(hr) || missing WSLC_COMPONENT_FLAG_NONE) { return hr; // 所有组件已就绪无需安装 } hr WslcInstallWithDependencies(missing, WSLC_INSTALL_OPTION_NONE, OnInstallProgress, myState);不传回调的场景若调用方对进度不敏感例如命令行工具静默安装可同时传nullptr与nullptrSDK 会跳过回调分支安装照常进行WinRT 桥接层的同步版本正是如此见下文。源码级实现原理回调在何处、以何种方式被触发在 wslcsdk.cpp 的WslcInstallWithDependencies实现中回调的触发遵循以下逻辑可作为理解进度语义的权威依据参数校验对components中未知的位返回E_INVALIDARG若包含WSLC_COMPONENT_FLAG_SDK_NEEDS_UPDATE直接返回WSLC_E_SDK_UPDATE_NEEDED——SDK 无法自行更新正在使用的自身调用方应升级 SDK 后重试。空组件短路components WSLC_COMPONENT_FLAG_NONE时立即返回S_OK不触发任何回调也不要求提升权限。权限检查安装组件需要管理员权限若当前线程令牌未提升且非 LocalSystem返回ERROR_ELEVATION_REQUIRED。因此回调触发前应先处理提权UAC。虚拟机平台阶段安装前后各触发一次回调0/1与1/1底层通过WslInstall::InstallOptionalComponent调用 DISM 启用c_optionalFeatureNameVmp可选功能若返回ERROR_SUCCESS_REBOOT_REQUIRED最终返回值为HRESULT_FROM_WIN32(ERROR_SUCCESS_REBOOT_REQUIRED)调用方可据此提示用户重启。WSL 运行时包阶段构造 lambda 将内部进度映射为0~100后回调底层走WindowsUpdateContext::RunUpdateFlow普通安装用EnsureProductRegistration修复模式用ResetProductRegistration驱动的 Windows Update 流程若更新计数为 0预览期包未发布等情况回退到 GitHub 发布端点拉取预发布包UpdatePackage(true, true, false)后回调 0 与 100 收尾。可以看出回调均发生在发起调用的线程上、同步执行。UI 应用若在主线程调用应在回调内尽快返回只做进度记录/消息投递避免阻塞安装主流程。WinRT 桥接层托管/现代应用如何复用同一回调WSLC SDK 的 WinRT 投影在 WslcService.cpp 中封装了该回调静态InstallProgressCallback把原生WslcComponentFlags转换为winrt::Microsoft::WSL::Containers::Component与progressSteps/totalSteps一起构造InstallProgress对象再通过ProgressCallbackHelper::ReportProgress投递给IAsyncActionWithProgressInstallProgress的进度令牌。异步版本InstallWithDependenciesAsync在co_await winrt::resume_background()之后注册回调同步版本则传nullptr回调WslcService.cpp。这意味着 C#/WinRT 开发者可以在不接触原生指针的情况下获得等价的进度事件流。测试验证回调协议的边界行为仓库测试 WslcSdkTests.cpp 覆盖了该回调参与的几个关键契约可作为集成调试时的行为参考InstallWithDependencies_NoComponents_Succeeds传WSLC_COMPONENT_FLAG_NONE必须立即返回S_OK且无需提权、不触发回调。InstallWithDependencies_SdkNeedsUpdate_ReturnsError传WSLC_COMPONENT_FLAG_SDK_NEEDS_UPDATE必须返回WSLC_E_SDK_UPDATE_NEEDED。InstallWithDependencies_WslPackage_GhFallback404通过注册表 URL 覆盖Software\Microsoft\Windows\CurrentVersion\Lxss下的 GitHub 地址覆盖项将 WSL 包回退下载端点替换为本地返回 404 的假服务器验证下载失败时WslcInstallWithDependencies向上层暴露HTTP_E_STATUS_NOT_FOUND——即回调可能只推进到中途如progressSteps totalSteps后安装整体失败UI 层必须同时处理回调中断与 HRESULT 失败。实践要点与注意事项动态计算百分比以totalSteps为分母适配不同组件的刻度差异VMP 为 0/1WSL 包为 0/100。区分组件与阶段用component切换 UI 文案同一组件可能多次回调用progressSteps 0与progressSteps totalSteps判断开始/结束。保持回调轻量同步回调中不要做 UI 重绘、磁盘 IO 或网络请求仅记录进度或向消息循环投递更新。处理提权与重启调用前确保进程已提升返回值可能为ERROR_SUCCESS_REBOOT_REQUIRED需提示用户重启完成虚拟机平台启用。先查再装结合WslcGetMissingComponents避免对已安装组件的重复安装修复场景才使用WSLC_INSTALL_OPTION_REPAIR。不能安装 SDK 自身若查询结果显示WSLC_COMPONENT_FLAG_SDK_NEEDS_UPDATE请更新调用方所使用的 SDK 版本而不是将其传入安装流程。围绕该回调的完整 API 族组件标志、安装选项、缺失组件查询、端到端流程均可从 C API 参考索引 进入源码与测试路径为 wslcsdk.h、wslcsdk.cpp 与 WslcSdkTests.cpp便于进一步深入。【免费下载链接】WSLWindows Subsystem for Linux项目地址: https://gitcode.com/GitHub_Trending/ws/WSL创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考