如何在 Chocolatey 安装后刷新 PowerShell 会话的环境而无需打开新会话

Posted

技术标签:

【中文标题】如何在 Chocolatey 安装后刷新 PowerShell 会话的环境而无需打开新会话【英文标题】:How to refresh the environment of a PowerShell session after a Chocolatey install without needing to open a new session 【发布时间】:2018-03-27 06:33:57 【问题描述】:

我正在编写用于将 GitHub 源代码克隆到本地计算机的自动化脚本。 在我的脚本中安装 Git 后我失败了,它要求关闭/打开 powershell。 所以我安装Git后无法自动克隆代码。

这是我的代码:

iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
 choco install -y git
 refreshenv
 Start-Sleep -Seconds 15

 git clone --mirror https://$username:$password@$hostname/$username/$Projectname.git D:\GitTemp -q 2>&1 | % "$_"  

错误:

git : The term 'git' is not recognized as the name of a cmdlet, 
      function, script file, or operable program. 
      Check the spelling of the name, or if a path was included, 
      verify that the path is correct and try again.

请让我在不退出的情况下重新启动 PowerShell 应该放什么?

【问题讨论】:

【参考方案1】:

你有一个引导问题:

refreshenvUpdate-SessionEnvironment 的别名)通常是在choco install ... 命令之后使用环境变量更改更新当前会话的正确命令。

但是,在安装 Chocolatey 本身之后refreshenv / Update-SessionEnvironment 本身仅在 未来 PowerShell 会话中可用,因为加载这些命令是通过添加到配置文件$PROFILE,基于环境变量$env:ChocolateyInstall

也就是说,您应该能够模拟$PROFILE 在以后的会话中获取时,Chocolatey 所做的事情,以便能够立即使用 refreshenv / Update-SessionEnvironment,之后立即安装 Chocolatey:

iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))

choco install -y git

# Make `refreshenv` available right away, by defining the $env:ChocolateyInstall
# variable and importing the Chocolatey profile module.
# Note: Using `. $PROFILE` instead *may* work, but isn't guaranteed to.
$env:ChocolateyInstall = Convert-Path "$((Get-Command choco).Path)\..\.."   
Import-Module "$env:ChocolateyInstall\helpers\chocolateyProfile.psm1"

# refreshenv is now an alias for Update-SessionEnvironment
# (rather than invoking refreshenv.cmd, the *batch file* for use with cmd.exe)
# This should make git.exe accessible via the refreshed $env:PATH, so that it
# can be called by name only.
refreshenv

# Verify that git can be called.
git --version

注意:最初的解决方案使用. $PROFILE 而不是Import-Module ... 来加载Chocolatey 配置文件,依赖Chocolatey 已经更新了$PROFILE。但是,ferventcoder 指出 $PROFILE 的这种更新并不总是发生,因此不能依赖它。

【讨论】:

必须重新加载配置文件,否则有时 refreshenv 无法正常工作! @mklement0 如果您能引用feventcoder 的来源,那就太好了。我知道这是准确的,但我很想了解为什么会出现这种情况 @Mattisdada:我的理解是$PROFILE 仅在该文件已经存在 的情况下才会更新,但我没有官方文档可以指出,所以我建议你问\ @ferventcoder 本人。 如果你愿意假设(我对此不好),你也可以使用Import-Module "$env:ProgramData\chocolatey\helpers\chocolateyInstaller.psm1"; Update-SessionEnvironment,其中$env:ProgramData\chocolatey 是 Chocolatey 自行安装的默认路径。 在 choco 之外使用 refreshenv 从 github.com/chocolatey/choco/tree/stable/src/… 和 Import-Module ... 获取 Get-EnvironmentVariable.ps1, Get-EnvironmentVariableNames.ps1, Update-SessionEnvironment.ps1, Write-FunctionCallLogMessage.ps1【参考方案2】:

你可以尝试使用Update-SessionEnvironment:

更新当前 powershell 会话的环境变量 Chocolatey 软件包安装期间可能发生的任何环境变量更改。

这将测试该更改在巧克力调用后是否仍然有效。

如果没有,一个简单的解决方法是至少使用绝对路径来调用git

致call Git from Powershell:

new-item -path alias:git -value 'C:\Program Files\Git\bin\git.exe'

那你可以试试:

git clone --mirror https://$username:$password@$hostname/$username/$Projectname.git D:\GitTemp -q 2>&1 | % "$_"  

【讨论】:

@PriyaRani 这就是我建议的替代使用 Git 完整路径的方法:C:\path\to\git.exe clone --mirror ... 但是,先生,我想在安装 git 后运行一次命令,它应该克隆 repo .....如果我传递 git 的路径,它会抛出错误路径无法识别...,C:\Program : 术语“C:\Program”未被识别为 cmdlet、函数的名称 iex ((New-Object System.Net.WebClient).DownloadString('chocolatey.org/install.ps1') ) choco install -y git refreshenv Start-Sleep -Seconds 15 git clone --mirror https://$username:$password@$hostname/$username/$Projectname.git D:\G跨度> @PriyaRani 使用引号:"C:\Program Files\path\to\git.exe" clone... 在加上引号时遇到问题:-“表达式或语句中出现意外的标记‘克隆’”.......“C:\Program Files\Git\bin\git.exe " clone github.com/Priyaran ... + ~~~~~~ 表达式或语句中出现意外的标记 'clone'。 + CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException + FullyQualifiedErrorId : UnexpectedToken OP 确实尝试使用Update-SessionEnvironment,即通过其refreshenv 别名,但问题是这些命令在安装 Chocolatey 后还不能立即使用。虽然您的别名定义命令有效,但更简单、更惯用的定义是 Set-Alias git 'C:\Program Files\Git\bin\git.exe'。此外,虽然您的方法恰好适用于 git,但并非所有 Chocolatey 安装的软件包都安装到通常的位置,因此更可靠的方法是找到一种方法来引导使用 Update-SessionEnvironment / refreshenv【参考方案3】:

我选择低技术解决方案:

$env:Path += ";C:\Program Files\Git\bin"

【讨论】:

【参考方案4】:

尽我最大的努力让它成为一个单行,但由于 PATH 变量需要特殊处理,如果不做一个愚蠢的长行,我就无法做到这一点。从好的方面来说,您不需要依赖任何第三方模块:

foreach ($s in 'Machine','User') 
  [Environment]::GetEnvironmentVariables($s).GetEnumerator().
  Where($_.Key -ne 'PATH') | ForEach-Object 
    [Environment]::SetEnvironmentVariable($_.Key,$_.Value,'Process') 

$env:PATH = ( ('Machine','User').ForEach(
  [Environment]::GetEnvironmentVariable('PATH',$_)).
  Split(';').Where($_) | Select-Object -Unique ) -join ';'

代码的范围仅限于流程,因此您不必担心会出现任何问题(不是这样,我测试过)。

注意:这不会删除在当前会话中创建的唯一命名的环境变量,因此如果您定义了 $env:FOO = 'bar' 并且“FOO”通常不是您的环境变量之一,$env:FOO 仍将即使在上面的代码运行之后也返回bar

【讨论】:

赞成作为不依赖其他 choco 函数运行的 choco Update-SessionEnvironment 版本。为我解决了一个问题,谢谢。

以上是关于如何在 Chocolatey 安装后刷新 PowerShell 会话的环境而无需打开新会话的主要内容,如果未能解决你的问题,请参考以下文章

使用 PackageParams 安装 Chocolatey 错误解析第二个参数

windows下通过Chocolatey安装node.js

windows下通过Chocolatey安装node.js

windows上更酷的软件安装方式—chocolatey

Chocolatey安装与使用

无法在 Windows 10 版本 1903 上安装 Chocolatey