JDK多版本切换脚本(Windows, PowerShell)

331 阅读1分钟

脚本功能:

  • 检查环境变量Path是否包含%JAVA_HOME%\bin, 没有则增添
  • 修改环境变量JAVA_HOME
  • 本脚本修改的环境变量是用户变量, 若想修改系统变量, 要改一下脚本

使用方法:

  • 下载多个JDK到电脑
  • 保存以下文本到脚本jdk-path.ps1
  • 修改$JDK_PATHS变量到JDK版本真实路径
  • 使用PowerShell执行脚本
  • 建议: 脚本生成快捷方式, 右键属性 -> 快捷方式 -> 目标 -> 启动方式改为powershell -File "脚本路径"

环境变量USERPROFILE相当于C:\Users\[用户名]\

脚本编写关键点:

  1. 读取ItemProperty是转义后的值, 不是原值%JAVA_HOME%\bin, 因此用$regKey读取
  2. JAVA_HOME和Path在注册表中必须需要写成REG_EXPAND_SZ类型, 而不是REG_SZ类型
  3. 若用了REG_SZ类型, 只有Windows Terminal读到转义后的正确值, 其他Terminal不行
  4. 必须先写入%JAVA_HOME%\binPath, 再写入JAVA_HOME, 若顺序反了, Path不生效
$JDK_PATHS = [ordered]@{
    "8"  = "$env:USERPROFILE\.jdks\adopt-openjdk-1.8.0_302"
    "17" = "$env:USERPROFILE\.jdks\temurin-17.0.10"
    "21" = "$env:USERPROFILE\.jdks\openjdk-21.0.2"
}

Write-Host "Current JDK Version:"
Write-Host "============================================="
java -version 2>&1 | Write-Host
Write-Host "============================================="

Write-Host "Supported JDK Versions:"
$JDK_PATHS.Keys | ForEach-Object { Write-Host "  JDK $_" }
Write-Host "============================================="

$opt = Read-Host "Select JDK version"
if (-not $JDK_PATHS.Contains($opt)) {
    Write-Host "Invalid version selected!"
    exit 1
}

$regKey = [Microsoft.Win32.Registry]::CurrentUser.OpenSubKey("Environment", $false)
$rawPath = $regKey.GetValue("Path", "", [Microsoft.Win32.RegistryValueOptions]::DoNotExpandEnvironmentNames)
$regKey.Close()
if ($rawPath -like "*%JAVA_HOME%\bin*") {
    Write-Host "%JAVA_HOME%\bin already in user Path"
} else {
    if (!$rawPath.EndsWith(';')) { $rawPath += ";" }
    $newPath = $rawPath + "%JAVA_HOME%\bin;"
    Set-ItemProperty -Path "HKCU:\Environment" -Name "Path" -Value $newPath -Type ExpandString
    Write-Host "%JAVA_HOME%\bin added to user Path"
}

$JAVA_HOME = $JDK_PATHS[$opt]
Write-Host "Selected JDK Home: $JAVA_HOME"
[Environment]::SetEnvironmentVariable("JAVA_HOME", $JAVA_HOME, "User") # User/Machine
Set-ItemProperty -Path "HKCU:\Environment" -Name "JAVA_HOME" -Value $JAVA_HOME -Type ExpandString
Write-Host "JAVA_HOME updated"

Write-Host "Press any key to exit..."
[Console]::ReadKey($true) | Out-Null