How to change a environment variable in PowerShell and launch an application

前端 未结 1 1233
南旧
南旧 2021-01-06 07:35

In PowerShell, I need to change the system path variable:

$oldPath = [System.Environment]::GetEnvironmentVariable(\'Path\', \'Machine\')
[System.Environment]         


        
相关标签:
1条回答
  • 2021-01-06 08:07

    In general, child processes inherit the environment from the parent process*. If you spawn a new PowerShell session from an existing PowerShell session, the new session will inherit the environment variables from that session (but no other variables).

    However, the Path variable is an exception that causes a lot of confusion: Even though it's an environment variable, new PowerShell sessions read its value from the registry key HKLM:\System\CurrentControlSet\Control\Session Manager\Environment, overriding the value inherited from a parent session.

    • This behavior is specific to the Path variable. Other environment variables are inherited from the parent session regardless of whether they were defined only in the parent session or are stored in the aforementioned registry key.

    • This behavior is also specific to PowerShell.

      » If you change Path in a PowerShell session, but not in the registry, and spawn a new PowerShell session (e.g. with start powershell), the new session will have the path from the registry, but if you spawn a cmd session, the new session will have the path from the PowerShell session that spawned it.

      » Likewise, if you change Path in a cmd session (with set Path=New Path) and spawn a PowerShell session, the new session will have the path from the registry, but if you spawn a cmd session, it will have the changed path from the parent cmd session.

      » The default behavior is to inherit the path (along with the rest of the environment) from the parent process (as cmd does). However, it's quite possible that some other programs behave in a similar fashion to PowerShell, overriding the inherited value with the registry value. This behavior is not common, but the possibility can't be ruled out that this happens with your executable.

    The following commands change Path in the current session, and not in the registry:

    $env:Path = 'New path'
    

    [System.Environment]::SetEnvironmentVariable('Path', 'New Path', 'Process')
    


    The following commands change Path in the registry, and not in the current session:

    Set-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Control\Session Manager\Environment' -Name 'Path' -Value 'New Path'
    

    [System.Environment]::SetEnvironmentVariable('Path', 'New Path', 'Machine')
    

    What you're describing doesn't make sense to me, because you say that you've tried one method that changes the path in the registry, and one that changes the path in the PowerShell session, and that the executable you're spawning doesn't have the changed path either way. AFAIK the original environment isn't cached anywhere, and the child process has to be getting the path from either the parent process's environment or the registry.

    What I suggest it to make absolutely sure you've changed the path both ways before launching the executable:

    1. Open a PowerShell session
    2. Change the path using one of the methods that changes it in the session
    3. Change the path using one of the methods that changes it in the registry
    4. Launch the executable

    If for some inexplicable reason that doesn't work, try this:

    1. Open a PowerShell session
    2. Change the path using one of the methods that changes it in the registry
    3. Rather than launching the executable directly from that PowerShell session, execute this command

      powershell "& $someExeName 'someargument'"
      

      to have the executable launched by a new but non-interactive PowerShell session that will read the Path environment variable from the registry.


    * Note that the inheritance of the environment is the only relationship between parent and child processes in Windows. Other than that they're completely independent (there's no hierarchy as there is in Unix and Linux).

    0 讨论(0)
提交回复
热议问题