С этим сценарием связаны три проблемы:
- При использовании
[Environment]::SetEnvironmentVariable
с любой областью, отличной от Process
, он не обновляет среду текущего процесса
Если вы хотите установить его постоянно , а также повлиять на текущий процесс, вам нужно вызвать его дважды.
Вы обновляете пользовательскую область действия компьютера
и с теми же значениями
При Windows переменные среды процесса по умолчанию создаются путем наложения пользовательской среды по умолчанию на верх машинной среды по умолчанию. Таким образом, с одной стороны, избыточно , чтобы установить одинаковое значение JAVA_HOME для одного и того же значения в обеих областях.
Вы обновляете значения по умолчанию
PATH на основе объединенного значения в процессе
Переменные пути являются специальными. Значения процесса представляют собой комбинацию среды пользователя и машины. Поэтому то, что является просто избыточным в других переменных среды, может вызвать реальные проблемы с переменными PATH , поскольку добавление папки к обоим значениям приводит к двум ее копиям в пути к среде вашего процесса.
Из-за этого вы никогда не должны устанавливать для пользовательской области или области машины значение, которое находится в процессе, но особенно не следует устанавливать их обе.
Например:
- Если пользовательское значение было просто "C: \ Users \ Jaykul \ Documents \ PowerShell \ Scripts"
- И значение компьютера было просто "C: \ Windows \ System32"
- Процесс получит "C: \ Windows \ System32; C: \ Users \ Jaykul \ Documents \ PowerShell \ Scripts"
Если вы возьмете это и добавите что-нибудь к нему, а затем установите его на оба , вы получите два из всех в вашем новом PATH, когда вы начнете новый процесс.
правильно сделать следующее:
- Изменить только одну область видимости (машина sco pe, или область пользователя).
- Обновление в зависимости от того, что вы обновляете.
- Также обновите область процесса, чтобы вы могли узнать, что происходит.
У меня есть модуль "Environment", который находится в галерее PowerShell и github , который имеет функцию Add-Path , которая выполняет все это, но Основы таковы:
function Add-Path {
param($Path, [ValidateSet("User","Machine")]$Scope)
# Update what we were asked to update
[Environment]::SetEnvironmentVariable("Path",
([Environment]::GetEnvironmentVariable("Path", $Scope) + [IO.Path]::PathSeparator + $Path),
$Scope)
# Also update the process scope
[Environment]::SetEnvironmentVariable("Path",
([Environment]::GetEnvironmentVariable("Path", "Process") + [IO.Path]::PathSeparator + $Path),
"Process")
}
Конечно, функция в модуле, с которым я связан, делает больше, чем гарантирует, что не будет дупликов, и обязательно вставляет новый путь в процесс в нужном месте. (т.е. область действия машины перед областью пользователя), но это основы ...