我想从脚本文件重新加载我的用户配置文件。我认为从脚本文件中获取它的点可以解决问题,但它不起作用:
# file.ps1
. $PROFILE
但是,如果我从 PowerShell 的解释器中点源它,它确实有效。
我为什么要这样做?
每次我更新我的配置文件并想要测试它时,我都会运行这个脚本,所以我想避免重新启动 PowerShell 来刷新环境。
我想从脚本文件重新加载我的用户配置文件。我认为从脚本文件中获取它的点可以解决问题,但它不起作用:
# file.ps1
. $PROFILE
但是,如果我从 PowerShell 的解释器中点源它,它确实有效。
我为什么要这样做?
每次我更新我的配置文件并想要测试它时,我都会运行这个脚本,所以我想避免重新启动 PowerShell 来刷新环境。
如果您想从脚本全局刷新您的个人资料,则必须运行该脚本“点源”。
当您运行脚本时,所有配置文件脚本都在“脚本”范围内运行,并且不会修改您的“全局”范围。
为了让脚本修改您的全局范围,它需要是“点源”或以句点开头。
. ./yourrestartscript.ps1
您在“yourrestartscript.ps1”中有您的个人资料脚本“dot-sourced”。您实际上正在做的是告诉“yourrestartscript”在当前范围内运行,并且在该脚本内,您是在告诉 $profile 脚本在脚本的范围内运行。由于脚本的作用域是全局作用域,因此配置文件中的任何变量集或命令都将发生在全局作用域中。
与跑步相比,这并没有给你带来太多优势
. $profile
因此,您标记为答案的方法可能在 Powershell 命令提示符内有效,但在 PowerShell ISE(对我而言,它提供了卓越的 PowerShell 会话)内无效,并且可能无法在其他 PowerShell 环境中正常工作.
这是一个我已经使用了一段时间的脚本,它在每个环境中都非常适合我。我只是将这个函数放入 ~\Documents\WindowsPowerShell 的 Profile.ps1 中,每当我想重新加载我的配置文件时,我都会对函数进行点源,即
. Reload-Profile
这是功能:
function Reload-Profile {
@(
$Profile.AllUsersAllHosts,
$Profile.AllUsersCurrentHost,
$Profile.CurrentUserAllHosts,
$Profile.CurrentUserCurrentHost
) | % {
if(Test-Path $_){
Write-Verbose "Running $_"
. $_
}
}
}
& $profile
用于重新加载配置文件。
如果您的配置文件设置了别名或执行失败的导入,那么您将看到错误,因为它们已经在配置文件的先前加载中设置。
你为什么要这样做?
因为它可能会创建重复项(附加到 $env:path)和设置常量/只读对象的问题导致错误。
最近在microsoft.public.windows.powershell上有一个关于此主题的主题。
如果您尝试重置会话的状态,则无法执行此操作,即使使用内部范围 ( $host.EnterNestedPrompt()
),因为能够在“所有范围”设置变量/别名/...。
我找到了这个解决方法:
#some-script.ps1
#restart profile (open new powershell session)
cmd.exe /c start powershell.exe -c { Set-Location $PWD } -NoExit
Stop-Process -Id $PID
更详细的版本:
#publish.ps1
# Copy profile files to PowerShell user profile folder and restart PowerShell
# to reflect changes. Try to start from .lnk in the Start Menu or
# fallback to cmd.exe.
# We try the .lnk first because it can have environmental data attached
# to it like fonts, colors, etc.
[System.Reflection.Assembly]::LoadWithPartialName("System.Diagnostics")
$dest = Split-Path $PROFILE -Parent
Copy-Item "*.ps1" $dest -Confirm -Exclude "publish.ps1"
# 1) Get .lnk to PowerShell
# Locale's Start Menu name?...
$SM = [System.Environment+SpecialFolder]::StartMenu
$CurrentUserStartMenuPath = $([System.Environment]::GetFolderPath($SM))
$StartMenuName = Split-Path $CurrentUserStartMenuPath -Leaf
# Common Start Menu path?...
$CAD = [System.Environment+SpecialFolder]::CommonApplicationData
$allUsersPath = Split-Path $([System.Environment]::GetFolderPath($CAD)) -Parent
$AllUsersStartMenuPath = Join-Path $allUsersPath $StartMenuName
$PSLnkPath = @(Get-ChildItem $AllUsersStartMenuPath, $CurrentUserStartMenuPath `
-Recurse -Include "Windows PowerShell.lnk")
# 2) Restart...
# Is PowerShell available in PATH?
if ( Get-Command "powershell.exe" -ErrorAction SilentlyContinue ) {
if ($PSLnkPath) {
$pi = New-Object "System.Diagnostics.ProcessStartInfo"
$pi.FileName = $PSLnkPath[0]
$pi.UseShellExecute = $true
# See "powershell -help" for info on -Command
$pi.Arguments = "-NoExit -Command Set-Location $PWD"
[System.Diagnostics.Process]::Start($pi)
}
else {
# See "powershell -help" for info on -Command
cmd.exe /c start powershell.exe -Command { Set-Location $PWD } -NoExit
}
}
else {
Write-Host -ForegroundColor RED "Powershell not available in PATH."
}
# Let's clean up after ourselves...
Stop-Process -Id $PID
这只是上面 guillermooo 答案中两行脚本的改进,它没有让新的 PowerShell 窗口进入我的正确目录。我相信这是因为 $PWD 是在新的 PowerShell 窗口的上下文中评估的,这不是我们希望 set-location 处理的值。
function Restart-Ps {
$cline = "`"/c start powershell.exe -noexit -c `"Set-Location '{0}'" -f $PWD.path
cmd $cline
Stop-Process -Id $PID
}
按理说它不应该工作,因为它吐出的命令行格式不正确,但它似乎可以完成这项工作,这对我来说已经足够了。
因为几年后我偶然发现了这一点,所以我想补充一点,您可以使用调用运算符:&
将您的配置文件与默认变量加载到您的配置文件:$profile
。
因此,如果您的会话以某种方式无法加载您的个人资料(使用 cmder/conemu 发生在我身上),只需键入:
& $profile
我用它来解决需要永远加载的配置文件。
开始运行:
powershell_ise -noprofile
然后我运行了这个:
function Reload-Profile {
@(
$Profile.AllUsersAllHosts,
$Profile.AllUsersCurrentHost,
$Profile.CurrentUserAllHosts,
$Profile.CurrentUserCurrentHost
) | % {
if(Test-Path $_){
Write-Verbose "Running $_"
$measure = Measure-Command {. $_}
"$($measure.TotalSeconds) for $_"
}
}
}
. Reload-Profile
感谢@Winston Fassett 让我更接近于找到我的问题。