win的环境变量管理脚本,像linux一样通过脚本管理环境变量

危险!!!本脚本会操作环境变量,请备份环境变量后再操作

危险!!!本脚本不会删除原有的路径,但是会覆盖同名路径,没有撤销功能

每次改完这个脚本再运行一下就自动写入了

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..."
相关推荐
Joren的学习记录2 小时前
【Linux运维进阶知识】Nginx负载均衡
linux·运维·nginx
用户2190326527352 小时前
Java后端必须的Docker 部署 Redis 集群完整指南
linux·后端
胡先生不姓胡2 小时前
如何获取跨系统调用的函数调用栈
linux
Jtti3 小时前
服务器防御SYN Flood攻击的方法
运维·服务器
2501_941982053 小时前
RPA 的跨平台部署与统一自动化策略
运维·自动化·rpa
b***25113 小时前
电池自动分选机:精密分选保障新能源产业质量核心
运维·自动化·制造
数数科技的数据干货3 小时前
游戏流失分析:一套经实战检验的「流程化操作指南」
大数据·运维·人工智能·游戏
蒟蒻要翻身4 小时前
在同一局域网内共享打印机设置指南
运维
一点晖光4 小时前
搭建内网穿透的ngrok服务器
服务器·内网穿透·ngrok
里纽斯4 小时前
RK平台Watchdog硬件看门狗验证
android·linux·rk3588·watchdog·看门狗·rk平台·wtd