Невозможно установить PATH с помощью SetEnvironmentVariable - PullRequest
1 голос
/ 03 октября 2019

Я пытаюсь установить переменную окружения в моем скрипте powershell.

Вот мой фрагмент кода. Он устанавливает системную переменную среды (Системные свойства> Переменная среды> Путь), однако я не могу запустить rabbitmq-сервис в powershell.

В выводе команды '$ ENV: PATH' нет нового добавленного пути. После перезапуска системы $ ENV: PATH содержит новый путь, но команда 'rabbitmq-service' по-прежнему не работает.

  # SET Erlang and RabbitMQ  Home Path
    $ERLANG_HOME = "$env:PROGRAMFILES\erl9.2"
    [System.Environment]::SetEnvironmentVariable("ERLANG_HOME", $ERLANG_HOME, "Machine")

    $ERTS_HOME = "$env:PROGRAMFILES\erts-9.2"
    [System.Environment]::SetEnvironmentVariable("ERTS_HOME", $ERTS_HOME, "Machine")

    $RABBITMQ_HOME = "$env:PROGRAMFILES\RabbitMQ Server\rabbitmq_server-3.6.11" 
    [System.Environment]::SetEnvironmentVariable("RABBITMQ_HOME", $RABBITMQ_HOME, "Machine")


    # Add Erlang and RabbitMQ to Path     
    $System_Path_Elems = [System.Environment]::GetEnvironmentVariable("PATH", "Machine").Split(";")
    if (!$System_Path_Elems.Contains("$RABBITMQ_HOME\sbin") -and !$System_Path_Elems.Contains("$ERLANG_HOME\bin") -and !$System_Path_Elems.Contains("$ERTS_HOME\bin"))
    {       
    $newPath = [System.String]::Join(";", $System_Path_Elems + "$ERLANG_HOME\bin" + "$ERTS_HOME\bin" + "$RABBITMQ_HOME\sbin")
    [System.Environment]::SetEnvironmentVariable("PATH", $newPath, "Machine")   
    }

Если я задаю PATH, используя $ env: PATH, как показано ниже в моем сценарии, это работает,

$env:Path += ";C:\\Program Files\\erl9.2\\erts-9.2\\bin;
C:\\Program Files\\RabbitMQ Server\\rabbitmq_server-3.6.11\\sbin;C:\\Program Files\\erl9.2\\bin"  

Я могу выполнить следующие команды без каких-либо проблем.

rabbitmq-service remove
rabbitmq-plugins enable rabbitmq_management --offline
rabbitmq-service install
rabbitmq-service start

Итак, почему SetEnvironmentVariable не работает. Я что-то здесь упускаю?

1 Ответ

3 голосов
/ 03 октября 2019
$env:PATH = ...

эквивалентно (префикс пространства имен System. подразумевается):

[Environment]::SetEnvironmentVariable(
  'PATH', 
   ..., 
   [EnvironmentVariableTarget]::Process
)

PowerShell автоматически преобразует строки в значения перечисления, поэтому 'Process' вместо [EnvironmentVariableTarget]::Process также работает.

То есть в обоих случаях вы обновляете переменную среды только для только текущего процесса - будущие сеансы будут не см. обновленное значение.

В отличие от этого, если вы используете [Environment]::SetEnvironmentVariable() с целями [EnvironmentVariableTarget]::Machine / [EnvironmentVariableTarget]::User, вы обновите постоянные определения для всей машины / только для текущего пользователя, без обновления значения в текущем процессе ;то есть эти определения вступают в силу только в будущих сеансах.

К сожалению, нет одиночного вызова, который позволил бы вам сделать оба , поэтому вам потребуется два звонка:

# Update the current process' env.var
$env.PATH = ... 
# Also persist the new value.
# Note that targeting [EnvironmentVariableTarget]::Machine requires
# ELEVATION (running as admin).
[Environment]::SetEnvironmentVariable('PATH', $env:PATH, <target>)
...