危险!!!本脚本会操作环境变量,请备份环境变量后再操作
危险!!!本脚本不会删除原有的路径,但是会覆盖同名路径,没有撤销功能
每次改完这个脚本再运行一下就自动写入了
win的环境变量管理特别麻烦,path还有长度限制,而且配置XXX_HOME之后还要在path中配置XXX_HOME\bin等等,很麻烦,还容易配错,所以 可以使用下面的工具进行配置,
bash
@{ N="UV_DEFAULT_INDEX"; V="https://pypi.tuna.tsinghua.edu.cn/simple"; P="_none" }
N代表键,V代表值,P代表要不要在path中写
其中P可以有以下写法:
- _none是不在path中写,但是在path外面写XXX_HOME
- _self是把自己XXX_HOME写到path中 ,并在path外面写XXX_HOME
- xxx任意字符是把XXX_HOME\xxx写到path中,并在path外面写XXX_HOME
- P=@("_self", "Scripts") 表示多个,即XXX_HOME和XXX_HOME\Scripts,并在path外面写XXX_HOME
bash
$ExtraPathEntries = @(
"C:\Windows\System32\Wbem"
)
这个表示直接将改路径写到path中
bash
$topPriorityVars = @("%$ProxyVarName%")
置顶项
不要照抄EnvConfigList ,改成你自己的
bash
<#
.SYNOPSIS
Windows 环境变量配置工具 (修复版)
#>
# ================= 0. 核心函数定义 (修复报错的关键) =================
function Get-RegistryRawValue {
param(
[string]$Name,
[string]$Path = "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"
)
$key = [Microsoft.Win32.Registry]::LocalMachine.OpenSubKey($Path, $false)
if ($null -ne $key) {
# 获取原始值 (不展开 %变量%)
$val = $key.GetValue($Name, $null, [Microsoft.Win32.RegistryValueOptions]::DoNotExpandEnvironmentNames)
$key.Close()
return $val
}
return $null
}
function Set-RegistryValue {
param(
[string]$Name,
[string]$Value,
[bool]$IsExpand = $false,
[string]$Path = "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"
)
$key = [Microsoft.Win32.Registry]::LocalMachine.OpenSubKey($Path, $true)
if ($null -ne $key) {
if ($IsExpand) {
$key.SetValue($Name, $Value, [Microsoft.Win32.RegistryValueKind]::ExpandString)
} else {
$key.SetValue($Name, $Value, [Microsoft.Win32.RegistryValueKind]::String)
}
$key.Close()
}
}
# ================= 1. 统一配置区域 =================
$EnvConfigList = @(
# --- JetBrains & VM Options ---
@{ N="UV_DEFAULT_INDEX"; V="https://pypi.tuna.tsinghua.edu.cn/simple"; P="_none" }
@{ N="APPCODE_VM_OPTIONS"; V="C:\jetbra\vmoptions\appcode.vmoptions"; P="_none" }
@{ N="CLION_VM_OPTIONS"; V="C:\jetbra\vmoptions\clion.vmoptions"; P="_none" }
@{ N="DATAGRIP_VM_OPTIONS"; V="C:\jetbra\vmoptions\datagrip.vmoptions"; P="_none" }
@{ N="DATASPELL_VM_OPTIONS"; V="C:\jetbra\vmoptions\dataspell.vmoptions"; P="_none" }
@{ N="DEVECOSTUDIO_VM_OPTIONS"; V="C:\jetbra\vmoptions\devecostudio.vmoptions"; P="_none" }
@{ N="GATEWAY_VM_OPTIONS"; V="C:\jetbra\vmoptions\gateway.vmoptions"; P="_none" }
@{ N="GOLAND_VM_OPTIONS"; V="C:\jetbra\vmoptions\goland.vmoptions"; P="_none" }
@{ N="JETBRAINSCLIENT_VM_OPTIONS"; V="C:\jetbra\vmoptions\jetbrainsclient.vmoptions"; P="_none" }
@{ N="JETBRAINS_CLIENT_VM_OPTIONS"; V="C:\jetbra\vmoptions\jetbrains_client.vmoptions"; P="_none" }
@{ N="PHPSTORM_VM_OPTIONS"; V="C:\jetbra\vmoptions\phpstorm.vmoptions"; P="_none" }
@{ N="PYCHARM_VM_OPTIONS"; V="C:\jetbra\vmoptions\pycharm.vmoptions"; P="_none" }
@{ N="RIDER_VM_OPTIONS"; V="C:\jetbra\vmoptions\rider.vmoptions"; P="_none" }
@{ N="RUBYMINE_VM_OPTIONS"; V="C:\jetbra\vmoptions\rubymine.vmoptions"; P="_none" }
@{ N="STUDIO_VM_OPTIONS"; V="C:\jetbra\vmoptions\studio.vmoptions"; P="_none" }
@{ N="WEBIDE_VM_OPTIONS"; V="C:\jetbra\vmoptions\webide.vmoptions"; P="_none" }
@{ N="WEBSTORM_VM_OPTIONS"; V="C:\jetbra\vmoptions\webstorm.vmoptions"; P="_none" }
@{ N="IDEA_VM_OPTIONS"; V="C:\jetbra\vmoptions\idea.vmoptions"; P="_none" }
# ================= 编程语言 & 运行时 =================
@{ N="JAVA_HOME"; V="C:\Program Files (x86)\jdk"; P="bin" }
@{ N="PYTHON_HOME"; V="D:\software\Anaconda\envs\base-py312"; P=@("_self", "Scripts") }
@{ N="NODE_HOME"; V="C:\Program Files\nodejs"; P="_self" }
@{ N="NVM_HOME"; V="D:\software\nvm"; P="_self" }
@{ N="LUA_HOME"; V="D:\software\lua-5.4.2_Win64_bin"; P="_self" }
@{ N="R_HOME"; V="D:\software\R\R-4.4.0"; P="bin" }
@{ N="SCALA_HOME"; V="D:\software\Scala"; P="bin" }
@{ N="POWERSHELL_7_HOME"; V="D:\software\PowerShell-7.4.5-win-x64"; P="_self" }
@{ N="LEAN4_HOME"; V="D:\software\lean-4.12.0-rc1-windows"; P="bin" }
@{ N="JVMS_HOME"; V="D:\software\jvms"; P="_self" }
@{ N="JAVA_HOME2"; V="D:\software\jvms\store\8.0.42"; P="_none" }
# ================= 开发工具 & CLI =================
@{ N="GIT_HOME"; V="D:\software\Git"; P="bin" }
@{ N="VISUAL_STUDIO_HOME"; V="D:\software\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.39.33519"; P=@("bin\Hostx64\x64","include") }
@{ N="LAZYGIT_HOME"; V="D:\software\lazygit_0.44.1_Windows_x86_64"; P="_self" }
@{ N="DONET_HOME"; V="C:\Program Files\dotnet\"; P="_self" }
@{ N="GITHUBCLI_HOME"; V="D:\software\GitHub CLI\"; P="_self" }
@{ N="MAVEN_HOME"; V="D:\software\apache-maven-3.9.6"; P="bin" }
@{ N="CMAKE_HOME"; V="D:\software\cmake-3.16.0-rc1-win64-x64"; P="bin" }
@{ N="NASM_HOME"; V="D:\software\nasm-2.16.03"; P="_self" }
@{ N="FFMPEG_HOME"; V="D:\software\ffmpeg-7.1.1-full_build"; P="bin" }
@{ N="MINGW_HOME"; V="D:\software\CLion 2023.3.4\bin\mingw"; P="bin" }
@{ N="MSYS64_UCRT64_HOME"; V="D:\software\msys64\ucrt64"; P="bin" }
@{ N="OPNE_OCD_HOME"; V="D:\software\openocd-0.12.0"; P="bin" }
@{ N="RIPGREP_HOME"; V="D:\software\ripgrep-15.1.0-aarch64-pc-windows-msvc"; P="_self" }
@{ N="LSD_HOME"; V="D:\software\lsd-v1.1.5-x86_64-pc-windows-msvc"; P="_self" }
@{ N="UV_HOME"; V="C:\Users\root\.local\bin"; P="_self" }
@{ N="VIM_HOME"; V="D:\software\Vim\vim91"; P="_self" }
@{ N="CLINK_DIR"; V="D:\software\clink"; P="_self" }
@{ N="BANDZIP_HOME"; V="D:\software\bandzip\Bandizip"; P="_self" }
@{ N="GRAPHVIZ_HOME"; V="D:\software\Graphviz 2.44.1"; P="bin" }
@{ N="TEX_HOME"; V="D:\software\texlive\2024"; P="bin\windows" }
@{ N="NMAP_HOME"; V="D:\software\Nmap"; P="_self" }
@{ N="NSSM_HOME"; V="D:\software\nssm-2.24\win64"; P="_self" }
@{ N="PT8HOME"; V="D:\software\Cisco Packet Tracer 8.0"; P="bin" }
@{ N="ChocolateyInstall"; V="C:\ProgramData\chocolatey"; P="bin" }
# ================= 容器 & 虚拟化 =================
@{ N="DOCKER_HOME"; V="C:\Program Files\Docker\Docker\resources"; P="bin" }
@{ N="LAZYDOCKER_HOME"; V="D:\software\lazydocker_0.23.3_Windows_x86_64"; P="_self" }
@{ N="VMWARE_HOME"; V="D:\software\VMware"; P="_none" }
# ================= 数据库 & 大数据 =================
@{ N="MYSQL_HOME"; V="D:\software\mysql-5.7.42-3306"; P="bin" }
@{ N="POSTGRESQL_HOME"; V="D:\software\pgsql"; P="bin" }
@{ N="MONGO_HOME"; V="C:\Program Files\MongoDB\Server\8.2"; P="bin" }
@{ N="REDIS_HOME"; V="D:\software\redis"; P="_self" }
@{ N="NEO4J_HOME"; V="D:\software\neo4j-community-5.19.0"; P="bin" }
@{ N="TOMCAT_HOME"; V="D:\software\apache-tomcat-8.5.100"; P="bin" }
@{ N="HADOOP_HOME"; V="E:\data\hadoop\hadoop-3.1.3"; P="bin" }
# ================= AI & GPU =================
@{ N="CUDA_HOME"; V="C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.4"; P=@("_self", "bin") }
@{ N="NVIDIA_HOME"; V="C:\Program Files\NVIDIA Corporation"; P="NVIDIA App\NvDLISR" }
@{ N="OLLAMA_HOME"; V="E:\data\C\ollama\Ollama"; P="_self" }
@{ N="PAI_MODEL_DIR"; V="E:\data\Topaz Photo AI BETA\models"; P="_none" }
@{ N="GIGAPIXEL_HOME"; V="D:\software\Topaz Gigapixel AI"; P="bin" }
# ================= 其他工具 =================
@{ N="OH_MY_POSH_HOME"; V="D:\software\oh-my-posh"; P="_self" }
@{ N="ADB_HOME"; V="D:\software\platform-tools"; P="_self" }
@{ N="BVSSH_HOME"; V="D:\software\BvSshClient"; P="_self" }
@{ N="AGSDESKTOPJAVA"; V="D:\software\ArcGIS\Desktop10.8\"; P="bin" }
@{ N="MSMPI_BENCHMARKS"; V="C:\Program Files\Microsoft MPI\Benchmarks\"; P="_self" }
@{ N="MSMPI_BIN"; V="C:\Program Files\Microsoft MPI\Bin\"; P="_self" }
@{ N="NPM_GLOBAL_HOME"; V="E:\data\npm\node_global"; P="_self" }
# ================= 纯配置变量 (不加 Path) =================
@{ N="KMP_DUPLICATE_LIB_OK"; V="TRUE"; P="_none" }
@{ N="COREPACK_ENABLE_STRICT"; V="0"; P="_none" }
@{ N="MKL_SERIAL"; V="YES"; P="_none" }
@{ N="OLLAMA_HOST"; V="0.0.0.0:11434"; P="_none" }
@{ N="OLLAMA_MODELS"; V="E:\data\ollama"; P="_none" }
@{ N="HADOOP_USER_NAME"; V="root"; P="_none" }
@{ N="CONDA_HOME"; V="D:\software\Anaconda"; P=@("Scripts", "Library\bin") }
@{ N="LINGO64_18_HOME"; V="D:\software\Lingo\"; P="_self" }
@{ N="NEOVIM_HOME"; V="D:\software\Neovim\bin"; P="_self" }
@{ N="NVITOP_HOME"; V="D:\software\nvitop-main"; P="_self" }
@{ N="WOLFRAMSCRIPT"; V="C:\Program Files (x86)\Wolfram Research\WolframScript\"; P="_self" }
@{ N="Classpath"; V="D:\software\Lingo\Lingo18.jar"; P="_none" }
@{ N="USBIPD_HOME"; V="C:\Program Files\usbipd-win"; P="_self" }
# --- 系统/驱动类 ---
@{ N="DriverData"; V="C:\Windows\System32\Drivers\DriverData"; P="_none" }
@{ N="ComSpec"; V="%SystemRoot%\system32\cmd.exe"; P="_none" }
@{ N="OS"; V="Windows_NT"; P="_none" }
@{ N="PROCESSOR_ARCHITECTURE"; V="AMD64"; P="_none" }
@{ N="NUMBER_OF_PROCESSORS"; V="32"; P="_none" }
@{ N="USERNAME"; V="SYSTEM"; P="_none" }
@{ N="PSModulePath"; V="%ProgramFiles%\WindowsPowerShell\Modules;%SystemRoot%\system32\WindowsPowerShell\v1.0\Modules;C:\Program Files (x86)\Microsoft SQL Server\160\Tools\PowerShell\Modules\"; P="_none" }
)
$ExtraPathEntries = @(
"C:\Windows\System32\Wbem"
)
# ================= 2. 执行逻辑 (开始运行) =================
if (-not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
Write-Warning "需要管理员权限!请右键 -> [使用 PowerShell 运行]"
Read-Host "按回车退出..."
Exit
}
Write-Host "正在初始化配置..." -ForegroundColor Cyan
$Log_EnvAdded = New-Object System.Collections.Generic.List[string]
$Log_PathAction = New-Object System.Collections.Generic.List[string]
$Log_ForeignPaths = New-Object System.Collections.Generic.List[string]
$DevPathEntries = New-Object System.Collections.Generic.List[string]
# --- Step A: 预处理配置,生成 $DevPathEntries 和设置环境变量 ---
foreach ($item in $EnvConfigList) {
$name = $item.N
$val = $item.V
$policy = $item.P
# 1. 设置环境变量本身 (xx_HOME)
$currentRaw = Get-RegistryRawValue -Name $name
if ($currentRaw -ne $val) {
Set-RegistryValue -Name $name -Value $val -IsExpand $false
$Log_EnvAdded.Add("设置变量: `"$name`" = `"$val`"")
}
# 2. 根据策略解析需要添加到 Path 的绝对路径
if ($policy -eq "_none") { continue }
$pathsToAdd = @()
if ($policy -is [array]) {
$pathsToAdd = $policy
} else {
$pathsToAdd = @($policy)
}
foreach ($p in $pathsToAdd) {
$fullEntry = ""
if ($p -eq "_self") {
$fullEntry = $val # 直接使用值作为路径
} else {
# 简单拼接: 值 + \ + 子目录
$fullEntry = "$val\$p"
}
# 规范化路径 (去除多余斜杠等)
try {
# 注意: 如果路径包含 %变量% 可能导致 GetFullPath 报错,这里简单处理
if ($fullEntry -notmatch "%") {
$fullEntry = [System.IO.Path]::GetFullPath($fullEntry)
}
} catch { }
$DevPathEntries.Add($fullEntry)
}
}
# 添加额外的手动路径
foreach ($extra in $ExtraPathEntries) {
$DevPathEntries.Add($extra)
}
# --- Step B: 更新注册表备份变量 _DEV_PATHS ---
$ProxyVarName = "_DEV_PATHS"
# 去重并强制转为 String 数组
[string[]]$uniquePaths = $DevPathEntries | Select-Object -Unique | ForEach-Object { [string]$_ }
$proxyString = $uniquePaths -join ";"
$currentProxyRaw = Get-RegistryRawValue -Name $ProxyVarName
if ($currentProxyRaw -ne $proxyString) {
# IsExpand = true 以防万一,虽然这里存的是绝对路径
Set-RegistryValue -Name $ProxyVarName -Value $proxyString -IsExpand $true
$Log_PathAction.Add("已更新聚合变量 $ProxyVarName (包含 $($uniquePaths.Count) 个条目)")
}
# --- Step C: 清洗 Path 并 组装 (头部优先策略) ---
$rawPath = Get-RegistryRawValue -Name "Path"
if ($null -eq $rawPath) { $rawPath = "" }
[string[]]$currentParts = $rawPath -split ";" | Where-Object { $_.Trim() -ne "" }
$cleanPathList = New-Object System.Collections.Generic.List[string]
# 定义必须置顶的变量
$topPriorityVars = @("%$ProxyVarName%")
foreach ($part in $currentParts) {
$cleanPart = $part.Trim()
# 1. 如果是置顶变量,先跳过 (稍后强制加到头)
if ($topPriorityVars -contains $cleanPart) { continue }
# 2. 移除旧的标记
if ($cleanPart -match "^%_MY_PATH_GROUP") { continue }
# 3. [关键清洗] 检查此路径是否已被 _DEV_PATHS 管理
# 如果 Path 中的某个绝对路径已经存在于我们的 uniquePaths 列表中,则从主 Path 中移除
$isManaged = $false
# 为了比对准确,统一去除末尾斜杠
$cleanCheck = $cleanPart.TrimEnd("\")
foreach ($devEntry in $uniquePaths) {
if ($cleanCheck -eq $devEntry.TrimEnd("\")) {
$isManaged = $true
break
}
}
if ($isManaged) {
# 已被归档到 _DEV_PATHS 中,不添加到主 Path
} else {
# 外部保留 (如 System32 等)
$cleanPathList.Add($cleanPart)
$Log_ForeignPaths.Add($cleanPart)
}
}
# --- 最终组装 ---
$FinalList = New-Object System.Collections.Generic.List[string]
# 强制置顶
foreach ($topVar in $topPriorityVars) {
$FinalList.Add($topVar)
}
# 添加外部路径
$FinalList.AddRange($cleanPathList)
$finalPath = $FinalList -join ";"
if ($finalPath -ne $rawPath) {
Set-RegistryValue -Name "Path" -Value $finalPath -IsExpand $true
$Log_PathAction.Add("主 Path 已更新")
$Log_PathAction.Add(" - 置顶项: $topPriorityVars")
$Log_PathAction.Add(" - 外部保留项数: $($cleanPathList.Count)")
}
# --- Step D: 广播 ---
Write-Host "`n正在刷新系统环境..." -ForegroundColor Yellow
$code = @"
using System;
using System.Runtime.InteropServices;
public class Win32Abs {
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern IntPtr SendMessageTimeout(IntPtr hWnd, uint Msg, UIntPtr wParam, string lParam, uint fuFlags, uint uTimeout, out UIntPtr lpdwResult);
}
"@
if (-not ("Win32Abs" -as [type])) { Add-Type -TypeDefinition $code }
[UIntPtr]$r = [UIntPtr]::Zero
[Win32Abs]::SendMessageTimeout([IntPtr]0xffff, 0x001A, [UIntPtr]::Zero, "Environment", 0x0002, 5000, [ref]$r) | Out-Null
# ================= 3. 最终报告 =================
Write-Host "=========== 环境变量配置报告 ===========" -ForegroundColor Cyan
if ($Log_PathAction.Count -gt 0) {
Write-Host "`n[Path 变更]" -ForegroundColor Yellow
foreach ($l in $Log_PathAction) { Write-Host $l -ForegroundColor Green }
} else {
Write-Host "`npath无新增变化" -ForegroundColor Gray
}
if ($Log_EnvAdded.Count -gt 0) {
Write-Host "`n[其它环境变量变更]" -ForegroundColor Yellow
foreach ($l in $Log_EnvAdded) { Write-Host $l -ForegroundColor Green }
} else {
Write-Host "`n其它环境变量无新增变化" -ForegroundColor Gray
}
Write-Host "`n---------- Path中保留的其它内容 (审计) ----------" -ForegroundColor DarkGray
foreach ($fp in $Log_ForeignPaths) {
if ($fp -like "%SystemRoot%*" -or $fp -like "C:\WINDOWS*") {
Write-Host " $fp (System)" -ForegroundColor Gray
} else {
Write-Host " $fp" -ForegroundColor Magenta
}
}
Write-Host "`n配置完成" -ForegroundColor Cyan
Read-Host "Done..."