如何在 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】:你有一个引导问题:
refreshenv
(Update-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 会话的环境而无需打开新会话的主要内容,如果未能解决你的问题,请参考以下文章