如何在PowerShell中更改环境变量并启动应用程序 [英] How to change a environment variable in PowerShell and launch an application

查看:288
本文介绍了如何在PowerShell中更改环境变量并启动应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

然后启动程序:

& $someExeName 'someargument'

我遇到的问题是可执行文件正在使用旧环境.它无法识别新路径.如果我还更改$env.path,以仅更改此PowerShell会话的路径,它也不会传播到新进程.如果我关闭PowerShell并在新窗口中启动可执行文件,就可以了.大概是从PowerShell进程继承了(未更新的)环境.

The problem I am getting is that the executable is using the old environment. It doesn't recognize the new path. If I also change $env.path, to change the path only for this PowerShell session, it also does not propagate to the new process. If I close PowerShell and launch the executable in a new window, it's fine. Presumably it's inheriting the (non-updated) environment from the PowerShell process.

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

What is the best practice for changing an environment variable in PowerShell, and having it recognized by new processes launched from that window?

推荐答案

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

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).

但是, Path 变量是一个引起大量混乱的异常:即使是环境变量,新的PowerShell会话也会从注册表项HKLM:\System\CurrentControlSet\Control\Session Manager\Environment中读取其值,从而覆盖继承的值来自父会话.

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.

  • 此行为特定于 Path 变量.其他环境变量是从父会话继承的,而不管它们是仅在父会话中定义还是存储在上述注册表项中.

  • 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.

此行为也特定于PowerShell.

This behavior is also specific to PowerShell.

»如果您在PowerShell会话中更改了 Path ,但在注册表中没有更改,并生成了一个新的PowerShell会话(例如,使用start powershell),则新会话将具有注册表中的路径,但是如果您生成一个cmd会话,新会话将具有生成它的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.

»同样,如果您在cmd会话(使用set Path=New Path)中更改 Path ,并生成PowerShell会话,则新会话将具有注册表中的路径,但是如果您生成cmd会话,则它将具有从父cmd会话更改的路径.

» 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.

»默认行为是从父进程继承路径(以及环境的其余部分)(与cmd一样). 但是,其他程序很有可能以与PowerShell类似的方式运行,将继承的值替换为注册表值.这种现象并不常见,但是不能排除这种情况是在您的可执行文件中发生的.

» 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')

您所描述的内容对我来说没有意义,因为您说您尝试过一种方法可以更改注册表中的路径,而另一种方法可以更改PowerShell会话中的路径,并且您可以执行'重新生成都没有改变路径的任何一种方式. AFAIK原始环境没有被缓存在任何地方,子进程必须从父进程的环境或注册表中获取路径.

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. 打开PowerShell会话
  2. 使用在会话中更改路径的方法之一更改路径
  3. 使用在注册表中更改路径的方法之一更改路径
  4. 启动可执行文件

如果由于某些莫名其妙的原因不起作用,请尝试以下操作:

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

  1. 打开PowerShell会话
  2. 使用在注册表中更改路径的方法之一更改路径
  3. 而不是直接从该PowerShell会话中启动可执行文件,而是执行此命令

  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'"

通过新的但非交互式PowerShell会话启动可执行文件,该会话将从注册表中读取 Path 环境变量.

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


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


* 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).

这篇关于如何在PowerShell中更改环境变量并启动应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆