首页/新闻资讯/正文详情

Winhance代码实现解析:PowerShell脚本生成引擎是如何工作的完整指南

发布时间:2026/9/25 3:37:30 来源:云帆数科 栏目:资讯中心
Winhance代码实现解析:PowerShell脚本生成引擎是如何工作的完整指南
Winhance代码实现解析PowerShell脚本生成引擎是如何工作的完整指南【免费下载链接】Winhance-zh_CNA Chinese version of Winhance. C# application designed to optimize and customize your Windows experience.项目地址: https://gitcode.com/gh_mirrors/wi/Winhance-zh_CNWinhance 是一款基于 C# 的 Windows 优化与定制工具它的核心能力之一就是自动生成 PowerShell 脚本来卸载预装应用、清理冗余功能并防止其重装。本文带你深入源码拆解这套 PowerShell 脚本生成引擎的设计思路与完整工作流程。为什么 Winhance 要生成脚本而不是直接执行很多系统优化工具在点击卸载时会立即执行命令而 Winhance 选择了一条更稳健的路先落盘、后执行把用户勾选的所有操作汇总成一个.ps1脚本文件保存到C:\Program Files\Winhance\Scripts\目录开机时自动运行通过 Windows 计划任务在系统启动时以 SYSTEM 权限执行脚本彻底移除新安装中可能重新出现的应用脚本可追溯用户随时可以打开BloatRemoval.ps1查看将被执行的内容透明且可手动修改这种生成脚本而非即时执行的设计也是 Winhance 与 UnattendedWinstall 思路一脉相承的地方——配置一次系统重启时自动生效。引擎全景6 个核心角色整套脚本生成引擎位于 ScriptGeneration/ 目录采用典型的职责分离 依赖注入架构共 6 个核心角色角色类名职责 模板提供器PowerShellScriptTemplateProvider提供各类 PowerShell 命令模板 脚本构建器PowerShellScriptBuilderService把模板和数据拼装成完整脚本文本 脚本工厂PowerShellScriptFactory生成结构化的RemovalScript对象✂️ 复合修改器CompositeScriptContentModifier从已有脚本中增删条目 脚本更新服务ScriptUpdateService维护已有BloatRemoval.ps1的内容⏰ 计划任务服务ScheduledTaskService注册开机自动执行的任务它们的接口定义集中在 Core 项目的 Interfaces/ 目录例如 IScriptBuilderService.cs 和 IScriptTemplateProvider.cs。实现与接口分离让上层业务代码完全不知道脚本具体是怎么拼出来的。第一步模板提供器准备零件PowerShellScriptTemplateProvider.cs 负责提供最底层的命令模板每个模板都是一个带占位符的字符串移除应用包Get-AppxPackage -Name {0} | Remove-AppxPackage ...第 28-33 行移除可选功能Get-WindowsCapability -Online | Where-Object ... | Remove-WindowsCapability -Online注册表操作值为空时生成reg delete否则生成reg add /t REG_DWORD ...第 49-59 行脚本头尾GetScriptHeader生成带时间戳的注释头GetScriptFooter写入一条关键命令——禁用 Windows 消费者功能云策略从根源上防止预装应用随系统更新回来模板模式的好处在于所有怎么写的知识都集中在这一个类里将来升级 Windows 版本导致命令变化时只需要修改这一处。第二步构建器把零件组装成完整脚本PowerShellScriptBuilderService.cs 是整个引擎的装配车间。它的核心方法BuildCompleteRemovalScript第 153-330 行做了四件事写脚本头调用模板提供器生成注释和生成时间合并应用包列表把主包和子包如 Copilot、Xbox 的附属包合并并用Distinct()去重生成$packages (...)数组按类型分段生成依次输出移除包、移除能力、禁用可选功能、注册表设置四个代码区块写脚本尾追加防止重装的策略命令和完成提示其中有两个很实用的细节注册表值类型转换GetRegTypeString把 C# 的RegistryValueKind映射成reg.exe认识的类型字符串如DWORD、SZFormatRegistryValue第 393-416 行则按类型决定是否给值加引号空值即删除注册表条目如果值为空会自动切换为reg delete删除模板一个字段同时表达了设置和删除两种语义第三步工厂产出可执行的 RemovalScript 对象PowerShellScriptFactory.cs 是面向上层的总装车间。CreateBatchRemovalScript第 38-72 行的返回值不是裸文本而是一个结构化的RemovalScript对象return new RemovalScript { Name BloatRemoval, Content scriptContent, TargetScheduledTaskName Winhance\\BloatRemoval, RunOnStartup true };它同时携带脚本内容、计划任务名、是否开机运行三项元信息后续保存和注册任务都基于这个对象进行。工厂里还有个巧妙的应用分类器CategorizeApps第 105-144 行用户只勾选了应用名工厂会查询应用目录WindowsAppCatalog把每个名字归类为标准包 / 可选能力 / 可选功能三种类型交给构建器生成对应的命令。查不到的名字默认按标准包处理保证脚本永远不会因为未知类型而漏掉条目。关键设计脚本不是一次性的而是活的这是引擎最有意思的部分。BloatRemoval.ps1会随着用户操作持续演进再次批量卸载时ScriptGenerationService.cs 会先检查脚本是否已存在——存在就走更新分支不存在才走新建分支当用户重新安装某个应用时UpdateBloatRemovalScriptForInstalledAppAsync第 293-488 行会反向操作把该应用从脚本的包数组里删掉否则开机会被脚本再次卸载从脚本里删条目由 CompositeScriptContentModifier.cs 实现它是个组合器把修改请求分发给四个专用修改器包 / 能力 / 功能 / 注册表。以 PackageScriptModifier.cs 为例它的做法是在脚本文本中定位$packages (起始位置找到数组结束符)截取整段数组逐行解析出包名移除目标条目重建数组文本把新数组替换回原文这种文本级差量更新避免了整体重建脚本可能破坏用户手动修改的问题同时也解释了为什么生成的脚本数组采用整齐的单行一个条目格式——方便机器解析。更新逻辑统一封装在 ScriptUpdateService.cs 中并通过isInstallOperation参数区分追加条目还是移除条目。最后一步计划任务让脚本开机自动生效脚本保存后ScheduledTaskService.cs 负责最后一公里。它的实现方式很务实不直接调用 COM API而是动态生成一段临时的 PowerShell 注册脚本第 85-122 行核心是这几行$action New-ScheduledTaskAction -Execute powershell.exe -Argument -ExecutionPolicy Bypass -File $scriptPath $trigger New-ScheduledTaskTrigger -AtStartup Register-ScheduledTask -TaskName $taskName -Action $action -Trigger $trigger -User SYSTEM -RunLevel Highest -Force注意三个关键点-AtStartup触发器系统启动时自动运行无需用户登录-User SYSTEM -RunLevel Highest以系统账户、最高权限执行确保Remove-AppxProvisionedPackage等需要管理员权限的命令能成功临时脚本用完即删注册脚本保存在%TEMP%执行完毕后自动清理不污染系统完整流程一图流把整条链路串起来一次批量卸载的旅程是用户在界面勾选应用 → ViewModel 收集勾选名单ScriptGenerationService检查BloatRemoval.ps1是否存在决定新建还是更新PowerShellScriptFactory把应用分类为包 / 能力 / 功能三类PowerShellScriptBuilderService按模板拼装出完整脚本文本SaveScriptAsync把脚本写入Program Files\Winhance\Scripts\BloatRemoval.ps1ScheduledTaskService注册Winhance\BloatRemoval计划任务下次开机时系统自动以 SYSTEM 权限执行脚本完成卸载并阻断重装架构亮点总结模板与数据彻底分离命令写法只在 PowerShellScriptTemplateProvider.cs 一处维护符合单一职责原则工厂模式产出对象而非文本RemovalScript携带任务名、开机标志等元数据让保存和任务注册解耦组合模式做差量修改CompositeScriptContentModifier聚合四个专用修改器新增脚本区域时只需新增一个修改器面向接口编程所有角色都先定义接口如 IScriptContentModifier.cs、IScriptFactory.csCore 项目引用接口、Infrastructure 项目提供实现项目边界清晰对于想学习 C# 工程化设计的读者src/Winhance.Infrastructure/Features/Common/ScriptGeneration/ 目录是一个非常值得研读的样本它展示了如何把一个生成文本文件这样看似简单的需求拆分成职责单一、可测试、易扩展的一组服务。【免费下载链接】Winhance-zh_CNA Chinese version of Winhance. C# application designed to optimize and customize your Windows experience.项目地址: https://gitcode.com/gh_mirrors/wi/Winhance-zh_CN创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关推荐

Databasus 前端工程规范:React 19 + FSD 分层架构、i18n 国际化与 Ant Design 编码标准的源码级实践
Databasus 前端工程规范:React 19 + FSD 分层架构、i18n 国际化与 Ant Design 编码标准的源码级实践

数据库灾备 【免费下载链接】databasus PostgreSQL backup tool with Point-In-Time-Recovery and restore verification 项目地址: https://gitcode.com/gh_mirrors/po/databasus 点击查看 免费下载 本文为 Databasus(一款支持 PostgreSQL 时间点恢复与… · 2026/9/25 3:37:30

什么是sprix-sage-router?A2A多智能体三模式路由完整入门指南
什么是sprix-sage-router?A2A多智能体三模式路由完整入门指南

什么是sprix-sage-router?A2A多智能体三模式路由完整入门指南 【免费下载链接】sprix-sage-router Sprix AI at 屿智同行 — state-aware SELF/COLLABORATE/HANDOFF routing for A2A agent networks. 项目地址: https://gitcode.com/gh_mirrors/sp/sprix-sage-rou… · 2026/9/25 3:37:24

中兴H10G-13刷当贝桌面全攻略:从TTL强刷到网络配置
中兴H10G-13刷当贝桌面全攻略:从TTL强刷到网络配置

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 3:37:24

自研综合网络安全扫描工具:从端口探测到指纹识别源码解析
自研综合网络安全扫描工具:从端口探测到指纹识别源码解析

简介:一份基于Python3开发的多功能网络安全扫描工具源码,面向安全测试人员、甲方自测团队及网络安全学习者,适用于敏感文件探测、WAF/CDN识别、端口扫描、服务识别、操作系统识别、弱口令检测、漏洞扫描、绕过CDN及旁站查询等授权安全评估场景… · 2026/9/25 4:04:39

录屏看不清细节?屏幕放大镜Pixelscope让局部放大成为教学利器
录屏看不清细节?屏幕放大镜Pixelscope让局部放大成为教学利器

录屏教学、程序演示、视频剪辑指导这类活儿,我算是做了不少年头了。有个问题每次都会碰到:明明自己操作得很清楚,屏幕上的细节也都能看到,可一旦把录制好的视频发给别人,立马就露怯了——鼠标那一点点移动轨迹、某个小… · 2026/9/25 4:04:39

华为USG6000E初始密码失效原因与重置全指南
华为USG6000E初始密码失效原因与重置全指南

1. 项目概述:为什么USG6000E的初始密码问题总让人抓狂?华为USG6000E系列防火墙,是很多企业网络边界部署的主力型号——它不是那种插上电就能用的傻瓜设备,而是一台需要精细配置的安全网关。但恰恰是这台“主力”,在开箱… · 2026/9/25 4:04:39

从空字段日期标题到内容补全:信息稀疏下的创作方法论
从空字段日期标题到内容补全:信息稀疏下的创作方法论

1. 先别急着查“历史上的今天”:把孤立的日期当线索,而不是答案接手这个任务时,我面前的输入只有一个:标题是“2026-01-08”,项目正文、关键词、摘要描述、热搜词、网络热词全为空。放在真实的创作场景里,这… · 2026/9/25 4:04:33

内蒙联通E900V21D盒子刷Armbian完整指南,让盒子变成7×24小时家庭Linux服务器
内蒙联通E900V21D盒子刷Armbian完整指南,让盒子变成7×24小时家庭Linux服务器

内蒙联通E900V21D盒子刷Armbian完整指南,让盒子变成724小时家庭Linux服务器 【免费下载链接】amlogic-s9xxx-armbian Supports running Armbian on Amlogic, Allwinner, and Rockchip devices. Support a311d, s922x, s905x3, s905x2, s912, s905d, s905x, s905w, s… · 2026/9/25 4:04:33

Icecream Ebook Reader评测:回归专注的本地电子书阅读体验
Icecream Ebook Reader评测:回归专注的本地电子书阅读体验

1. 从一次“反向折腾”说起:为什么我换回了本地阅读器我先坦白一件事:过去几年我几乎把主流阅读App装了个遍。手机里躺着三四个“书城”,每个都声称自己拥有海量资源和智能推荐,但用下来却越来越不对劲。打开App要先看开屏广告&am… · 2026/9/25 4:04:33

数值优化(Numerical Optimization)学习系列-03-共轭梯度方法(Conjugate Gradient)
数值优化(Numerical Optimization)学习系列-03-共轭梯度方法(Conjugate Gradient)

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:31

创维E900V22D刷机全攻略:S905L3SB芯片兼容性解析与救砖实战
创维E900V22D刷机全攻略:S905L3SB芯片兼容性解析与救砖实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:31

MQTT协议原理与Broker服务器搭建实战:从Mosquitto到EMQX
MQTT协议原理与Broker服务器搭建实战:从Mosquitto到EMQX

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:37

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码