简体   繁体   English

使用 Start-Process 保留环境变量

[英]Preserve environment variables using Start-Process

I'll start with saying that am new to Powershell.我将首先说这是 Powershell 的新手。 I'm currently trying to figure out how to set an environment variable in Windows 11 using the Start-Process cmdlet.我目前正在尝试弄清楚如何使用 Start-Process cmdlet 在 Windows 11 中设置环境变量。 I've already tried both with admin privileges and without.我已经尝试过使用管理员权限和没有管理员权限。 This is what I'm using:这就是我正在使用的:

Start-Process -FilePath "pwsh" -Verb runAs -ArgumentList "-Command `"& {`"`$env:WATCHDOG_PROCID = (Start-Process C:\Users\acqui\anaconda3\envs\prog\pythonw.exe {C:\Users\acqui\Documents\Programming\Projects\Watchdog\main.py $mode} -PassThru).Id`"; pause}`""

The variable, though, is neither created, if not already present, nor modified (checking by calling Get-ChildItem Env: from the pwsh that called the subprocess).但是,该变量既不会创建(如果尚未存在),也不会被修改(通过调用 Get-ChildItem Env: 从调用子进程的 pwsh 进行检查)。 The purpose in having WATCHDOG_PROCID is to be able to kill that precise process later on.拥有 WATCHDOG_PROCID 的目的是为了能够在以后终止该精确进程。

The process-specific environment variable you create is only visible to the pwsh process created by the outer Start-Process call, not also to the calling process .您创建的特定于进程的环境变量仅对外部Start-Process调用创建的pwsh进程可见,对调用进程也不可见

However, in your call the pwsh process automatically terminates after defining the environment variable, so the definition is lost.但是,在您的调用中, pwsh进程在定义环境变量后自动终止,因此定义丢失。

One option is to keep the pwsh session alive and continue working there , which you can do by placing the -NoExit CLI parameter before -Command .一种选择是保持pwsh会话处于活动状态并继续在那里工作,您可以通过在 -Command 之前放置-NoExit CLI参数来做到这-Command

If instead you want to define the environment variable in the calling process, make the pwsh call output the desired value (remove `$env:WATCHDOG_PROCID = from your command), capture it, and set it in the calling process.如果您想在调用进程中定义环境变量,请使pwsh调用输出所需的(从您的命令中删除`$env:WATCHDOG_PROCID = ),捕获它并在调用进程中设置它。


Note: There is no way to make all processes in the user's current OS session see a newly defined environment variable :注意:没有办法让用户当前操作系统会话中的所有进程都看到新定义的环境变量

When you define an environment variable persistently - via [System.Environment]::SetEnvironmentVariable() , as shown in this answer :当您通过[System.Environment]::SetEnvironmentVariable()持久定义环境变量时,如本答案所示:

  • Running processes typically do not pick up this change.正在运行的进程通常不会接受此更改。

    • Only if running processes are specifically designed to listen to environment changes, and act on them by reloading the redefined environment variable(s), do they see the change(s) right away.只有当正在运行的进程专门设计用于监听环境变化,并通过重新加载重新定义的环境变量来对它们采取行动时,它们才会立即看到变化。
  • Processes created later in the same OS session may see the changes, but that depends on how they are launched.稍后在同一操作系统会话中创建的进程可能会看到更改,但这取决于它们的启动方式。

    • For instance, processes launched later from a preexisting PowerShell session would not see the changes, because they inherit the PowerShell session's environment, and PowerShell itself is not designed to pick up persistent environment changes dynamically.例如,稍后从预先存在的 PowerShell 会话启动的进程将不到更改,因为它们继承了 PowerShell 会话的环境,而 PowerShell 本身并非旨在动态获取持久的环境更改。

In short:简而言之:

  • Given that you're trying to define a value that by definition only has meaning in the current OS session - the ID of a launched process - using a persistent environment variable is not the right storage mechanism, and a process-scoped environment variable must be set on a per-process basis.鉴于您正在尝试定义一个根据定义仅在当前操作系统会话中有意义的值 - 已启动进程的 ID - 使用持久环境变量不是正确的存储机制,并且进程范围的环境变量必须是在每个进程的基础上设置。

  • You could still use a persistent environment-variable definition, IF the other processes that need to know about the variable explicitly look up the definition in the registry .您仍然可以使用持久的环境变量定义,如果需要了解变量的其他进程显式查找注册表中的定义

    • Alternatively, you could designate a file to store the value in, or use a custom registry location.或者,您可以指定一个文件来存储该值,或使用自定义注册表位置。

    • Either way, the information will be stale when the current OS session ends, so you may need extra work to determine whether the currently persisted value is relevant to the current OS session or not (such as comparing the timestamp of when the persistent value was written to the timestamp of when the current OS session was started).无论哪种方式,当前 OS 会话结束时信息都会过时,因此您可能需要额外的工作来确定当前持久值是否与当前 OS 会话相关(例如比较写入持久值时的时间戳到当前操作系统会话开始时的时间戳)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM