如何在PowerShell中更改环境变量并启动应用程序

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在PowerShell中更改环境变量并启动应用程序相关的知识,希望对你有一定的参考价值。

在PowerShell中,我需要更改系统路径变量:

$oldPath = [System.Environment]::GetEnvironmentVariable('Path', 'Machine')
[System.Environment]::SetEnvironmentVariable('Path', (Transform-It $oldPath), 'Machine')

然后启动一个程序:

& $someExeName 'someargument'

我得到的问题是可执行文件正在使用旧环境。它无法识别新路径。如果我还更改$env.path,要仅更改此PowerShell会话的路径,它也不会传播到新进程。如果我关闭PowerShell并在新窗口中启动可执行文件,那很好。据推测,它继承了PowerShell流程中的(未更新的)环境。

在PowerShell中更改环境变量并通过从该窗口启动的新进程识别它的最佳实践是什么?

答案

通常,子进程从父进程*继承环境。如果从现有PowerShell会话生成新的PowerShell会话,则新会话将从该会话继承环境变量(但不包含其他变量)。

但是,Path变量是一个导致很多混淆的异常:即使它是一个环境变量,新的PowerShell会话也会从注册表项HKLM:SystemCurrentControlSetControlSession ManagerEnvironment读取其值,从而覆盖从父会话继承的值。

  • 此行为特定于Path变量。其他环境变量从父会话继承,无论它们是仅在父会话中定义还是存储在上述注册表项中。
  • 此行为也特定于PowerShell。 »如果在PowerShell会话中更改路径,但不在注册表中,并生成新的PowerShell会话(例如使用start powershell),则新会话将具有来自注册表的路径,但如果您生成cmd会话,则新会话将具有产生它的PowerShell会话的路径。 »同样,如果在cmd会话中更改Path(使用set Path=New Path)并生成PowerShell会话,则新会话将具有来自注册表的路径,但是如果您生成cmd会话,则它将具有来自父cmd的更改路径会话。 »默认行为是从父进程继承路径(以及环境的其余部分)(如cmd所示)。但是,很有可能其他一些程序的行为与PowerShell类似,用注册表值覆盖继承的值。这种行为并不常见,但不能排除可执行文件发生这种情况的可能性。

以下命令更改当前会话中的路径,而不是在注册表中:

$env:Path = 'New path'

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

以下命令更改注册表中的Path,而不是当前会话中的路径:

Set-ItemProperty -Path 'HKLM:SystemCurrentControlSetControlSession ManagerEnvironment' -Name 'Path' -Value 'New Path'

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

您所描述的内容对我没有意义,因为您说您已经尝试过一种方法来更改注册表中的路径,一种更改PowerShell会话中的路径,以及您正在生成的可执行文件两种方式都没有改变的路径。 AFAIK原始环境不会缓存在任何地方,子进程必须从父进程的环境或注册表获取路径。

我建议您确保在启动可执行文件之前已经双向改变了路径:

  1. 打开PowerShell会话
  2. 使用在会话中更改路径的方法之一更改路径
  3. 使用在注册表中更改它的方法之一更改路径
  4. 启动可执行文件

如果由于某些无法解释的原因不起作用,请尝试以下方法:

  1. 打开PowerShell会话
  2. 使用在注册表中更改它的方法之一更改路径
  3. 不是直接从该PowerShell会话启动可执行文件,而是执行此命令 powershell "& $someExeName 'someargument'" 使用可从注册表中读取Path环境变量的新但非交互式PowerShell会话启动可执行文件。

*请注意,环境的继承是Windows中父进程和子进程之间的唯一关系。除此之外,它们完全独立(没有像Unix和Linux那样的层次结构)。

以上是关于如何在PowerShell中更改环境变量并启动应用程序的主要内容,如果未能解决你的问题,请参考以下文章

设置Windows PowerShell环境变量

如何在配置文件中定义的 PowerShell 脚本中设置环境变量?

我想请教一下,powershell的脚本之间如何传递全局变量。

如何在不扩展令牌的情况下获取 PATH 环境变量的值?

在运行时将更改环境变量应用于应用程序

(23)Powershell中的首选项变量