零门槛指南:为Windows Defender Remover添加多语言支持
你是否曾因工具界面语言不通而放弃使用优秀的开源项目?作为一款旨在帮助全球用户移除Windows Defender组件的工具,Windows Defender Remover却长期受限于单一语言界面,这在跨国协作和全球推广中形成了无形壁垒。本文将带你从零开始构建完整的多语言支持系统,让这款工具真正实现"零语言障碍"使用。
读完本文你将掌握:
- 多语言架构设计的核心方法论
- PowerShell脚本国际化的实现技巧
- 注册表项多语言适配方案
- 自动化语言文件管理流程
- 跨版本兼容性保障策略
多语言支持现状分析
当前痛点诊断
通过对项目核心文件的深度分析,我们发现Windows Defender Remover在国际化支持方面存在显著短板:
# defender_remover13.ps1 中硬编码的英文提示
Write-Host "Select an option:`n"
Write-Host "Do you want to remove Windows Defender and alongside components? After this, you'll need to reboot."
这种将文本直接嵌入代码的方式导致:
- 新增语言需修改源代码,违反开闭原则
- 翻译工作与代码开发强耦合,协作效率低下
- 无法动态切换语言,用户体验割裂
技术栈适配评估
项目主要由三类文件构成,需针对性设计多语言方案:
| 文件类型 | 数量 | 当前国际化状态 | 适配难度 |
|---|---|---|---|
| PowerShell脚本 | 4 | 完全硬编码 | ★★★☆☆ |
| 注册表文件(.reg) | 18 | 部分支持多语言 | ★★☆☆☆ |
| 批处理文件(.bat) | 1 | 简单英文提示 | ★☆☆☆☆ |
多语言架构设计
系统架构图
核心组件职责
- 语言资源管理器:统一管理语言检测、加载和切换
- JSON语言文件:存储各语言文本资源,支持动态更新
- PowerShell适配层:提供多语言函数库,替代硬编码文本
- 注册表本地化器:动态生成多语言注册表项
实现步骤(分阶段执行)
阶段一:构建语言文件系统
1. 创建语言文件目录结构
# 执行以下命令创建标准化目录结构
mkdir -p .\Localization\Languages
mkdir -p .\Localization\Tools
2. 设计JSON语言文件规范
创建基础英文语言文件 .\Localization\Languages\en-US.json:
{
"common": {
"yes": "Yes",
"no": "No",
"confirm": "Confirm",
"cancel": "Cancel"
},
"main_menu": {
"title": "Defender Remover Script , version {version}",
"option_y": "Remove Windows Defender Antivirus + Disable All Security Mitigations",
"option_a": "Remove Windows Defender only, but keep UAC Enabled",
"option_s": "Disable All Security Mitigations",
"prompt": "Choose an option"
},
"warnings": {
"reboot_required": "Your PC will reboot in {seconds} seconds...",
"backup_recommended": "A system restore point is recommended before you run the script."
}
}
为支持中文,创建 .\Localization\Languages\zh-CN.json:
{
"common": {
"yes": "是",
"no": "否",
"confirm": "确认",
"cancel": "取消"
},
"main_menu": {
"title": "Defender移除脚本,版本 {version}",
"option_y": "移除Windows Defender及所有安全组件(需重启)",
"option_a": "仅移除Windows Defender,保留UAC",
"option_s": "禁用所有安全缓解措施",
"prompt": "请选择操作选项"
},
"warnings": {
"reboot_required": "您的电脑将在{seconds}秒后重启...",
"backup_recommended": "运行脚本前建议创建系统还原点。"
}
}
阶段二:开发多语言核心模块
1. 创建语言管理器 .\Localization\Tools\LangManager.ps1
function Initialize-LanguageSystem {
param(
[string]$DefaultLang = "en-US",
[string]$LangDir = ".\Localization\Languages"
)
# 检测系统语言
$systemLang = Get-WinSystemLocale | Select-Object -ExpandProperty Name
$langFile = Join-Path $LangDir "$systemLang.json"
# 回退到默认语言
if (-not (Test-Path $langFile)) {
$langFile = Join-Path $LangDir "$DefaultLang.json"
$systemLang = $DefaultLang
}
# 加载语言资源
$script:LangResources = Get-Content $langFile | ConvertFrom-Json
$script:CurrentLang = $systemLang
Write-Host "Loaded language: $systemLang" -ForegroundColor Green
}
function Get-LocalizedString {
param(
[string]$Key,
[hashtable]$Parameters = @{}
)
# 解析嵌套键 (例如 "main_menu.title")
$keys = $Key -split '\.'
$value = $script:LangResources
foreach ($k in $keys) {
if (-not $value.PSObject.Properties[$k]) {
Write-Warning "Missing translation for key: $Key"
return "[$Key]"
}
$value = $value.$k
}
# 处理参数替换 (例如 {version})
foreach ($param in $Parameters.GetEnumerator()) {
$value = $value -replace "{$($param.Key)}", $param.Value
}
return $value
}
2. 集成到主脚本
修改 defender_remover13.ps1,替换硬编码文本:
# 原代码
Write-Host "------ Defender Remover Script , version $defenderremoverver ------"
Write-Host "Select an option:`n"
Write-Host "Do you want to remove Windows Defender and alongside components? After this, you'll need to reboot."
Write-Host "[Y] Remove Windows Defender Antivirus + Disable All Security Mitigations"
Write-Host "[A] Remove Windows Defender only, but keep UAC Enabled"
Write-Host "[S] Disable All Security Mitigations"
$choice = Read-Host "Choose an option"
# 替换为
. .\Localization\Tools\LangManager.ps1
Initialize-LanguageSystem
Write-Host "------ $(Get-LocalizedString 'main_menu.title' @{version=$defenderremoverver}) ------"
Write-Host "$(Get-LocalizedString 'main_menu.prompt')`n"
Write-Host "$(Get-LocalizedString 'main_menu.warning')"
Write-Host "[Y] $(Get-LocalizedString 'main_menu.option_y')"
Write-Host "[A] $(Get-LocalizedString 'main_menu.option_a')"
Write-Host "[S] $(Get-LocalizedString 'main_menu.option_s')"
$choice = Read-Host $(Get-LocalizedString 'main_menu.choice_prompt')
阶段三:注册表文件本地化
1. 创建注册表模板系统
将 Remove_defender_moduled\DisableDefenderPolicies.reg 转换为模板 DisableDefenderPolicies.template.reg:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PolicyManager\default\Defender\AllowIOAVProtection]
"value"=dword:00000000
"comment"="{{defender.policy.allow_ioav_comment}}"
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender]
"DisableAntiSpyware"=dword:00000001
"comment"="{{defender.policy.disable_antispyware_comment}}"
2. 开发注册表生成器
创建 .\Localization\Tools\RegGenerator.ps1:
function Convert-TemplateToReg {
param(
[string]$TemplatePath,
[string]$OutputPath,
[string]$LangCode
)
# 加载对应语言文件
$langFile = ".\Localization\Languages\$LangCode.json"
$langData = Get-Content $langFile | ConvertFrom-Json
# 读取模板并替换占位符
$templateContent = Get-Content $TemplatePath -Raw
# 使用正则表达式匹配所有 {{...}} 占位符
$regex = '{{(.*?)}}'
$matches = [regex]::Matches($templateContent, $regex)
foreach ($match in $matches) {
$key = $match.Groups[1].Value
$keys = $key -split '\.'
$value = $langData
# 解析嵌套键
foreach ($k in $keys) {
if (-not $value.PSObject.Properties[$k]) {
Write-Warning "Missing translation for registry key: $key"
$value = "[$key]"
break
}
$value = $value.$k
}
# 替换占位符
$templateContent = $templateContent -replace [regex]::Escape($match.Value), $value
}
# 输出本地化注册表文件
$templateContent | Out-File $OutputPath -Encoding Unicode
}
# 批量处理所有模板
Get-ChildItem .\Remove_defender_moduled -Filter *.template.reg | ForEach-Object {
Convert-TemplateToReg -TemplatePath $_.FullName `
-OutputPath ($_.FullName -replace '\.template', '') `
-LangCode $script:CurrentLang
}
阶段四:用户界面与切换功能
1. 添加语言选择菜单
function Show-LanguageSelection {
$langFiles = Get-ChildItem .\Localization\Languages -Filter *.json | ForEach-Object {
$culture = $_.BaseName
$cultureName = (Get-Culture -Name $culture).DisplayName
[PSCustomObject]@{
File = $_.FullName
Code = $culture
Name = $cultureName
}
}
Write-Host "`n$(Get-LocalizedString 'language.select_title')`n"
for ($i=0; $i -lt $langFiles.Count; $i++) {
Write-Host "[$($i+1)] $($langFiles[$i].Name) ($($langFiles[$i].Code))"
}
$selection = Read-Host $(Get-LocalizedString 'language.enter_selection')
$selectedLang = $langFiles[$selection-1]
$script:LangResources = Get-Content $selectedLang.File | ConvertFrom-Json
$script:CurrentLang = $selectedLang.Code
Write-Host "$(Get-LocalizedString 'language.changed' @{name=$selectedLang.Name})" -ForegroundColor Green
}
2. 实现运行时切换
# 在主菜单添加语言切换选项
Write-Host "[L] $(Get-LocalizedString 'main_menu.option_language')"
# 处理语言切换选择
if ($choice -eq "L" -or $choice -eq "l") {
Show-LanguageSelection
# 重新显示主菜单
&$MyInvocation.MyCommand.Name
exit
}
阶段五:测试与部署
1. 自动化测试脚本
创建 .\Localization\Tools\Test-Localization.ps1:
function Test-AllLanguages {
$testResults = @()
Get-ChildItem .\Localization\Languages -Filter *.json | ForEach-Object {
$langCode = $_.BaseName
$langData = Get-Content $_.FullName | ConvertFrom-Json
# 测试核心键完整性
$requiredKeys = @(
'main_menu.title', 'main_menu.option_y',
'main_menu.option_a', 'main_menu.option_s',
'warnings.reboot_required'
)
$missingKeys = @()
foreach ($key in $requiredKeys) {
$keys = $key -split '\.'
$value = $langData
$valid = $true
foreach ($k in $keys) {
if (-not $value.PSObject.Properties[$k]) {
$valid = $false
break
}
$value = $value.$k
}
if (-not $valid) {
$missingKeys += $key
}
}
$testResults += [PSCustomObject]@{
Language = $langCode
Status = if ($missingKeys.Count -eq 0) { "PASS" } else { "FAIL" }
MissingKeys = $missingKeys -join ', '
FileSize = (Get-Item $_.FullName).Length
}
}
# 显示测试报告
$testResults | Format-Table -AutoSize
}
Test-AllLanguages
2. 部署与更新流程
高级功能扩展
1. 动态语言更新
function Update-LanguageFiles {
param(
[string]$UpdateServer = "https://defender-remover.localization.com/updates"
)
# 获取服务器语言列表
$remoteLangs = Invoke-RestMethod "$UpdateServer/languages.json"
foreach ($lang in $remoteLangs) {
$localPath = ".\Localization\Languages\$($lang.code).json"
# 检查是否需要更新
if (-not (Test-Path $localPath) -or
(Get-Item $localPath).LastWriteTime -lt [DateTime]$lang.lastUpdated) {
Write-Host "Updating $($lang.name) language file..."
Invoke-WebRequest "$UpdateServer/$($lang.code).json" -OutFile $localPath
}
}
}
2. 语言贡献者工具包
创建 .\Localization\CONTRIBUTING.md,包含:
- JSON文件格式规范
- 翻译优先级指南
- 测试流程说明
- 贡献者署名规则
兼容性与注意事项
系统版本支持矩阵
| Windows版本 | PowerShell版本 | 支持状态 | 特殊说明 |
|---|---|---|---|
| Windows 10 1809+ | 5.1+ | ✅ 完全支持 | 需要启用PS脚本执行 |
| Windows 11 21H2+ | 7.0+ | ✅ 完全支持 | 内置多语言支持更好 |
| Windows 8.1 | 4.0 | ⚠️ 有限支持 | 部分注册表项不兼容 |
性能优化建议
- 延迟加载:仅在需要时加载非活跃语言文件
- 缓存机制:缓存已解析的本地化字符串
- 异步更新:后台执行语言文件更新,不阻塞主流程
总结与后续计划
通过本方案,Windows Defender Remover将实现:
- 完全解耦的语言资源管理
- 动态切换的多语言界面
- 自动化的本地化流程
- 便捷的翻译贡献机制
后续迭代路线图
- 机器学习翻译助手:自动生成初步翻译草稿
- 社区翻译平台:Web界面简化翻译贡献
- 实时语言分析:统计各语言使用频率,优化翻译优先级
- 语音支持:为视觉障碍用户添加文本转语音功能
本文档及相关代码遵循项目LICENSE协议。如需贡献翻译,请提交PR至 https://gitcode.com/gh_mirrors/wi/windows-defender-remover 项目的Localization目录。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



