我想在文件中创建一组可以更新的别名,然后调用别名aa
以便文件执行并在当前会话中为我提供新别名。最终,我希望这些别名在PS启动时自动可用,因此我使用C:UsersAdministratorDocumentsWindowsPowerShellMicrosoft.PowerShell_profile.ps1
将它们放入。现在它看起来像:
$psdir="C:UsersAdministratorDocumentsWindowsPowerShell"
function Reload-Profile{
# . ${profile} DOES NOT WORK
# Write-Host ${profile}
# Write-Host $profile
# powershell $profile DOES NOT WORK
# Get-ChildItem "${psdir}*.ps1" | %{.$_} DOES NOT WORK
Write-Host "Custom PowerShell Environment Loaded"
}
function Edit-Profile
{
powershell_ise.exe $profile
}
Set-Alias show Get-ChildItem
Set-Alias show2 Get-ChildItem
Set-Alias aa Reload-Profile
Set-Alias ep Edit-Profile
如何执行此操作,以便在启动时加载别名,同时还可以使用aa
别名更新它们并将它们引入当前会话?
如果包含以下代码的评论的原始作者决定将其作为答案发布,只需在此答案中添加注释,我就会将其删除。因为已经两天了,我真的不希望他这样做。同时,这应该让人们更好地了解实际发生的事情。
# https://msdn.microsoft.com/en-us/powershell/reference/5.1/microsoft.powershell.utility/add-type
# Create a new cmdlet Reload-Profile using C# code and import it
Add-Type '
using System.Management.Automation;
using System.Management.Automation.Runspaces;
// https://msdn.microsoft.com/en-us/library/dd878294(v=vs.85).aspx
[Cmdlet("Reload", "Profile")]
public class ReloadProfileCmdlet : PSCmdlet {
protected override void EndProcessing()
{
// https://msdn.microsoft.com/en-us/library/ms568378(v=vs.85).aspx
// Runs $profile without parameters in the current context and displays the output and error
InvokeCommand.InvokeScript(". $profile", false, PipelineResultTypes.Output | PipelineResultTypes.Error, null);
}
}' -PassThru | Select -First 1 -ExpandProperty Assembly | Import-Module;
# Setup an alias for the new cmdlet
Set-Alias aa Reload-Profile
为了更好的可读性/突出显示 C# 代码独立:
using System.Management.Automation;
using System.Management.Automation.Runspaces;
// https://msdn.microsoft.com/en-us/library/dd878294(v=vs.85).aspx
[Cmdlet("Reload", "Profile")]
public class ReloadProfileCmdlet : PSCmdlet {
protected override void EndProcessing()
{
// https://msdn.microsoft.com/en-us/library/ms568378(v=vs.85).aspx
// Runs $profile without parameters in the current context and displays the output and error
InvokeCommand.InvokeScript(". $profile", false, PipelineResultTypes.Output | PipelineResultTypes.Error, null);
}
}
代码的问题在于,Reload-Profile
是一个函数,当你调用它时,它会为自己创建新的作用域。然后调用 . $profile
时,它不会为 profile 创建新的作用域,但仍会在Reload-Profile
作用域内调用。因此,当Reload-Profile
结束时,范围将被丢弃。因此,如果您使用别名,您还需要使用点调用运算符调用Reload-Profile
:. Reload-Profile
或 . aa
。
我假设,您的真正问题是"如何以一种不需要使用点调用运算符的方式制作aa
命令?
答案是使用已编译的 cmdlet 而不是 PowerShell 函数,因为 PowerShell 不会为 cmdlet 调用创建新的范围。然后,该 cmdlet 可以在当前范围内调用. $profile
。
Add-Type @‘
using System.Management.Automation;
using System.Management.Automation.Runspaces;
[Cmdlet("Reload", "Profile")]
public class ReloadProfileCmdlet : PSCmdlet {
protected override void EndProcessing() {
InvokeCommand.InvokeScript(
". $profile",
false,
PipelineResultTypes.Output | PipelineResultTypes.Error,
null
);
}
}
’@ -PassThru | Select -First 1 -ExpandProperty Assembly | Import-Module
Set-Alias aa Reload-Profile
附言我建议您使用不同的动词而不是Reload
,因为Reload
不包括在推荐的动词列表中,因此当您将Reload-Profile
导入会话时,Import-Module
会发出警告。