Powershell如何在按键上进行快速更改?

时间:2015-08-09 02:52:43

标签: .net windows powershell command-line

我是Powershell的新手。我正在尝试创建自己的自定义提示,显示当前目录的截断版本,除非您通过按CTRL + R展开它。而且,我想这样做:

$short\dir\path...>
*user presses CTRL+R*
$really\really\long\full\dir\path>
*Full dir path is shown as long as CTLR + R is held down*

3 个答案:

答案 0 :(得分:0)

我认为没有办法做到这一点,但我可以与你分享一个我喜欢使用的自定义提示:

function prompt {
    $Host.UI.RawUI.WindowTitle = Get-Location
    "[$env:COMPUTERNAME] PS> "
}

这会将当前计算机名称放在提示符中(您可能不需要这样做),但会将当前路径放在窗口标题中,其中长路径特别是不在路径中,并且不会使提示混乱。 / p>

答案 1 :(得分:0)

以下是一种方法,但它涉及很多妥协。首先它只在PS控制台中工作,而不是在ISE中工作,或者不在任何承载PS的应用程序中工作。其次,它将涉及大量的工作,取决于你想要体验的“顺畅”。第三,它可能会导致其他意想不到的事情发生。

基本上你为一个提示函数编写一个脚本,该函数轮询键盘,查找Ctrl-R或任何其他“动作”字符。通过“动作”字符,我的意思是输入,制表符,退格键,向上箭头,向下箭头等会导致某些事情发生。如果脚本看到Ctrl-R,那么您可以在标题栏或控制台中输出完整路径。如果将其输出到控制台,那么您的脚本必须确定控制台的哪一行包含当前提示。 Rawui成员包含此信息。

裸露的轮廓可能如下所示:

  do {
    sleep -milli 250
    if ($host.ui.rawui.keyavailable) {
      $key = $host.ui.rawui.readkey()
      if ($key.character -eq [char]'x') {
        write-host burp
      } else { break}
    }
  } while ($true)

每隔四分之一秒脚本就会看到一个密钥是否可用。如果是这样,它会读取密钥。如果键是'x'(ctrl-r为你),它输出“burp”。但是你要将'burp'更改为完整路径,以及将消息放在正确位置的逻辑(标题栏或控制台上的右行)。

如果键不是'x',那么这个简单的例子就会返回。这意味着'x'被“吃掉”而'x'功能在输出下一个提示之前不再有效。但是,您可以自己处理所有“操作”键而不是返回。如果按下向上箭头,您将检索上一个命令并将其输出到控制台。如果按下后退轴,则删除光标前的字符。如果按下tab,你必须与PS'内置命令完成交互(不确定是否可能)。等等。

最后,当用户按下return时,您需要将组成命令行的所有键提供给控制台(您可以使用WScript主机的SendKeys方法),或者您可以直接执行命令使用Invoke-Expression(iex)提示函数。如果你使用iex,PS保留的命令历史记录(即get-history)将不起作用,除非你找到一种方法来处理它(可能是Add-History?)。如果您使用SendKeys,那么有人可能会快速输入他的关键笔划穿插SendKeys。

作为妥协,不是自己处理所有“动作”键,你可以在按下ctrl-r之外的键时退出提示,并使用SendKeys将一个键发送到控制台,以防止来自被“吃掉”。这样你就可以通过20行脚本而不是几百行,而牺牲ctrl-r只能在键入任何字符之前工作。

另一个复杂因素。 readkey()允许您同时获得向下和向上键击。因此,只要按下ctrl-r中的'r',就可以显示完整路径。但是,您的脚本需要了解其他位置的向上/向下键击。这可能就像忽略向下击键一样简单。

这有一个好的方面。您可以在PS通常执行的范围之外实现密钥处理功能。因此,如果你想让ctrl-t显示当前时间,你可以这样做。如果你想让ctrl-w删除光标下的当前单词。

答案 2 :(得分:0)

这不是一个超级优雅的解决方案,但它基本上将Ctrl + Alt + R转换为热键以显示当前目录。您可以将和弦更改为“Ctrl + R”,但是您将覆盖PowerShell的默认PSReadlineKeyHandler。看起来它会卡在命令上,但是如果你开始键入,则会出现下一行。您需要将这两者添加到Microsoft.Powershell_Profile.ps1

中的$env:USERPROFILE\Documents\WindowsPowershell\
function prompt {
    if(($pwd | split-path -Parent | Split-Path -Leaf) -match ':')
    {
        "$pwd\>"
    }
    elseif (($pwd | Split-Path -Leaf) -match ':')
    {
        "$pwd>"
    }
    else {
        "...\$($pwd | split-path -Parent | Split-Path -Leaf)\$($pwd | Split-path -Leaf)\>"
    }
}

Set-PSReadlineKeyHandler -Chord "Ctrl+Alt+R" -ScriptBlock {
    write-host $pwd -nonewLine
}

希望这有帮助!