- ConvertFrom-Json 不支持 -Depth 参数(该参数只存在于 ConvertTo-Json), 5.1 下三处调用会直接报错终止,已实测复现并修复。 - 文件缺少 UTF-8 BOM,导致 5.1 用 -File 加载脚本时按系统代码页误读 中文/emoji 字符串,解析失败;PS7 默认按 UTF-8 解析不受影响。已加 BOM 修复。 已在本机 PowerShell 5.1 和 PowerShell 7 上分别实测通过(脚本解析 + test-fixtures 三种 profile 场景的 JSON 读写逻辑 + 幂等性)。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XBPAN7bzFphM8eMDwACmxs
140 lines
5.7 KiB
PowerShell
140 lines
5.7 KiB
PowerShell
# 强制启用 Chrome 中的 Gemini(Project Glic)(PowerShell 版本)
|
||
# 通过修补 Chrome 的 Local State 配置文件,绕过地区资格限制
|
||
# 支持系统:Windows
|
||
#
|
||
# PowerShell 原生自带 ConvertFrom-Json / ConvertTo-Json,天然是 JSON 感知的,
|
||
# 不需要像 macOS/Linux 那边为了避免依赖 jq 而手写括号深度扫描兜底方案。
|
||
|
||
Write-Host ""
|
||
Write-Host "🚀 Gemini in Chrome Enabler" -ForegroundColor Cyan
|
||
Write-Host ""
|
||
|
||
# Chrome 配置文件路径
|
||
$chromeStatePath = "$env:LOCALAPPDATA\Google\Chrome\User Data\Local State"
|
||
|
||
# 检查 Chrome 是否在运行;Local State 会在 Chrome 退出时被覆写,
|
||
# 所以修改前必须确保 Chrome 完全退出
|
||
$chromeProcesses = Get-Process -Name "chrome" -ErrorAction SilentlyContinue
|
||
if ($chromeProcesses) {
|
||
Write-Host "⚠️ Chrome 正在运行,请先完全退出再继续。" -ForegroundColor Yellow
|
||
Read-Host "关闭 Chrome 后按回车继续"
|
||
$chromeProcesses = Get-Process -Name "chrome" -ErrorAction SilentlyContinue
|
||
if ($chromeProcesses) {
|
||
Write-Host "❌ Chrome 仍在运行,请退出后重试。" -ForegroundColor Red
|
||
exit 1
|
||
}
|
||
}
|
||
|
||
# 检查配置文件是否存在
|
||
if (-not (Test-Path $chromeStatePath)) {
|
||
Write-Host "❌ 未找到 Chrome 配置文件:$chromeStatePath" -ForegroundColor Red
|
||
exit 1
|
||
}
|
||
|
||
# 备份原文件
|
||
$backupPath = "$chromeStatePath.bak"
|
||
Copy-Item -Path $chromeStatePath -Destination $backupPath -Force
|
||
Write-Host "✓ 已备份:Local State.bak" -ForegroundColor Green
|
||
|
||
# 探测本机安装的 Chrome 版本号(写入 variations_permanent_consistency_country 用)
|
||
function Get-ChromeVersion {
|
||
$candidates = @(
|
||
"$env:ProgramFiles\Google\Chrome\Application\chrome.exe",
|
||
"${env:ProgramFiles(x86)}\Google\Chrome\Application\chrome.exe",
|
||
"$env:LOCALAPPDATA\Google\Chrome\Application\chrome.exe"
|
||
)
|
||
foreach ($path in $candidates) {
|
||
if (Test-Path $path) {
|
||
return (Get-Item $path).VersionInfo.ProductVersion
|
||
}
|
||
}
|
||
return ""
|
||
}
|
||
|
||
$chromeVersion = Get-ChromeVersion
|
||
if (-not $chromeVersion) {
|
||
Write-Host "⚠️ 未能自动探测 Chrome 版本号,variations_permanent_consistency_country 的版本位会留空" -ForegroundColor Yellow
|
||
}
|
||
|
||
# 读取并解析 JSON
|
||
# 注意:ConvertFrom-Json 不接受 -Depth 参数(该参数只存在于 ConvertTo-Json;
|
||
# Windows PowerShell 5.1 下传了会直接报"找不到与参数名"Depth"匹配的参数"并终止执行)
|
||
$json = Get-Content -Path $chromeStatePath -Raw -Encoding UTF8 | ConvertFrom-Json
|
||
|
||
# 对可能不存在的属性做"存在则改、不存在则插入"的统一封装,
|
||
# 因为 PSCustomObject 对不存在的属性不能直接用 `=` 赋值
|
||
function Set-JsonProperty {
|
||
param(
|
||
[Parameter(Mandatory)] $Object,
|
||
[Parameter(Mandatory)] [string] $Name,
|
||
[Parameter(Mandatory)] $Value
|
||
)
|
||
if ($Object.PSObject.Properties.Name -contains $Name) {
|
||
$Object.$Name = $Value
|
||
} else {
|
||
$Object | Add-Member -NotePropertyName $Name -NotePropertyValue $Value -Force
|
||
}
|
||
}
|
||
|
||
Set-JsonProperty -Object $json -Name "variations_country" -Value "us"
|
||
Set-JsonProperty -Object $json -Name "variations_permanent_consistency_country" -Value @($chromeVersion, "us")
|
||
|
||
# profile.info_cache 下每个 profile 都补 is_glic_eligible,而不仅仅是已存在该字段的 profile
|
||
if (-not ($json.PSObject.Properties.Name -contains "profile")) {
|
||
$json | Add-Member -NotePropertyName "profile" -NotePropertyValue ([PSCustomObject]@{}) -Force
|
||
}
|
||
if (-not ($json.profile.PSObject.Properties.Name -contains "info_cache")) {
|
||
$json.profile | Add-Member -NotePropertyName "info_cache" -NotePropertyValue ([PSCustomObject]@{}) -Force
|
||
}
|
||
foreach ($entry in $json.profile.info_cache.PSObject.Properties) {
|
||
Set-JsonProperty -Object $entry.Value -Name "is_glic_eligible" -Value $true
|
||
}
|
||
|
||
# 写回:UTF-8 无 BOM(Chrome 要求),-Depth 同样要给够——
|
||
# 默认的 -Depth 2 会把深层嵌套对象压成 "System.Object[]" 之类的字符串,直接写坏配置
|
||
$newContent = $json | ConvertTo-Json -Depth 100 -Compress
|
||
$utf8NoBom = New-Object System.Text.UTF8Encoding $false
|
||
$tmpPath = "$chromeStatePath.tmp"
|
||
[System.IO.File]::WriteAllText($tmpPath, $newContent, $utf8NoBom)
|
||
|
||
# 校验写回的内容仍是合法 JSON,且目标字段确实生效;不合法就回滚、不覆盖原文件
|
||
try {
|
||
$verify = Get-Content -Path $tmpPath -Raw -Encoding UTF8 | ConvertFrom-Json
|
||
if ($verify.variations_country -ne "us") {
|
||
throw "variations_country 未生效"
|
||
}
|
||
Move-Item -Path $tmpPath -Destination $chromeStatePath -Force
|
||
} catch {
|
||
Write-Host "❌ 校验失败,已放弃本次修改(原文件未被触碰):$_" -ForegroundColor Red
|
||
Remove-Item -Path $tmpPath -ErrorAction SilentlyContinue
|
||
exit 1
|
||
}
|
||
|
||
# 汇报结果
|
||
Write-Host ""
|
||
$errors = 0
|
||
$final = Get-Content -Path $chromeStatePath -Raw -Encoding UTF8 | ConvertFrom-Json
|
||
if ($final.variations_country -eq "us") {
|
||
Write-Host "✓ variations_country 已设为 us" -ForegroundColor Green
|
||
} else {
|
||
Write-Host "⚠️ variations_country 未生效" -ForegroundColor Yellow
|
||
$errors++
|
||
}
|
||
$allEligible = $true
|
||
foreach ($entry in $final.profile.info_cache.PSObject.Properties) {
|
||
if ($entry.Value.is_glic_eligible -ne $true) { $allEligible = $false }
|
||
}
|
||
if ($allEligible) {
|
||
Write-Host "✓ is_glic_eligible 已对所有 profile 启用" -ForegroundColor Green
|
||
} else {
|
||
Write-Host "⚠️ 部分 profile 的 is_glic_eligible 未生效" -ForegroundColor Yellow
|
||
$errors++
|
||
}
|
||
|
||
Write-Host ""
|
||
if ($errors -eq 0) {
|
||
Write-Host "✅ 完成!请完全重启 Chrome 使改动生效。" -ForegroundColor Green
|
||
} else {
|
||
Write-Host "⚠️ 部分改动可能未生效,请检查 Chrome 版本。" -ForegroundColor Yellow
|
||
}
|