以编程方式读取在控制台窗口中选择的当前文本

Posted

技术标签:

【中文标题】以编程方式读取在控制台窗口中选择的当前文本【英文标题】:Programmatically read current text selected in console window 【发布时间】:2021-07-19 20:13:08 【问题描述】:

我已经构建了一个应用程序,它在命令提示符下接收用户的文本输入。我想允许用户选择文本并使用该文本,而不是要求用户输入。

在 linux/bash 中,这是通过调用“xsel”(一个 bash 实用程序)来实现的,它输出当前选择的文本,然后我将其通过管道传输到我的 python 脚本。在 Windows 中似乎没有一个简单的解决方案......知道如何在 Windows 的 python/batch/powershell/external 实用程序中获取当前选定的命令行文本吗?

谢谢!

【问题讨论】:

简单的解决方案是Read-Host。它会提示用户输入。将输入分配给变量也使其更易于使用。 $var = Read-host -Prompt 'what ya want',输入保存到$var @AbrahamZinala 会用鼠标吗? 在典型的 console.exe 中启用快速编辑。这使得选择复制然后粘贴变得更加容易。其中,当与 Read-Host 结合使用时,我认为非常接近请求。 不,您必须进行选择以供选择。可以选择使用 $host.ui 使用箭头键,但是从不同的 cli 中理解起来有点困难。 这能回答你的问题吗? How to get the word under the cursor in Windows? 【参考方案1】:

注意:我假设您只对当前控制台窗口中选择的文本感兴趣

据我所知,Windows 上没有完美的解决方案[1],但您可以近似一个,但是,需要用户的合作,其形式是在选择后右键单击

以下解决方案适用于常规控制台窗口 (conhost.exe) 和 Windows 终端:

在常规控制台窗口中,应启用“快速编辑”模式,以便用鼠标直接选择文本。

要使解决方案发挥作用,用户必须将所选内容复制到剪贴板,如果没有提供直接输入,稍后您可以检索剪贴板的内容。这很容易通过右键单击(窗口内的任何位置)在做出选择后实现,提示消息必须指示用户这样做。

这是一个例子:

# Since the selection can only be obtained via the clipboard and we don't want preexisting
# clipboard content to interfere with the operation, we clear the clipboard first.
Set-Clipboard '' 

# Define the prompt string to use with Read-Host containing instructions.
$prompt = @'
Enter a value and press Enter 
 - OR -
Select a string in this console window, RIGHT-CLICK and then press Enter
'@

# Prompt for user input until it is non-blank, either by direct input or via the selection.
do 
  $userInput = Read-Host $prompt
  if (-not $userInput)  # No direct input, try to get the selection from the clipboard.
    $userInput = Get-Clipboard
  
 while (-not $userInput.Trim())

Write-Verbose -Verbose @"
You entered or selected:

  «$userInput»

"@

[1] 虽然存在(非 PowerShell 友好)技术原则上查询 Windows 控制台的选择(涉及 - “软”已弃用 - GetConsoleSelectionInfo WinAPI 函数),或者更一般地说,允许“监视”UI 的跨应用程序 Windows Accessibility API,如 this answer 所示),这些技术不能被直接在控制台窗口中同步执行的代码使用本身,因为键入或提交命令总是涉及自动清除选择将控制权返回给shell/正在运行的程序。在常规控制台窗口中 - 但不是在 Windows 终端中 - 进行选择后的第一个 Enter 键实际上会将选择复制到剪贴板,然后 然后 清除选择并将控制权返回给外壳/正在运行的程序,因此按 Enter 两次 而不是右键单击然后按 Enter 也可以。ma​​cOS 上的终端也会先清除选择。 相比之下,在 Linux 上,在这种情况下,至少 基于 X-Window 的终端保留选择(已通过随附的 Gnome 终端验证) Ubuntu 18.04),正如您的问题所暗示的那样,可以与(按需安装)xsel 实用程序结合使用,以编程方式查询选择。

【讨论】:

很高兴听到它有帮助,@rubmz。我添加的脚注解释了阻碍更好解决方案的挑战。可能有办法克服它们,但需要大量的努力。 我不是在寻找完美的解决方案。在 Linux 上清除选择也是一个问题,我猜在任何终端中。但这对我的应用程序来说已经足够了。再次感谢!这是一个比我想象的更难解决的问题:-) @rubmz,是的,似乎应该有一个更简单的解决方案。当shell /在shell中运行的程序重新获得控制权时,唯一清除选择的终端是Ubuntu附带的Gnome终端,因此确实使用xsel(必须按需安装)在那里工作;我的猜测是所有基于 X-Windows 的终端都以这种方式运行。 @IInspectable,你漏掉了那句话的一半:“我们不建议在新产品中使用此内容,但我们将在未来无限期继续支持现有用法。” deprecation 一词含糊不清:它既可以指代将在未来版本中删除的功能,也可以指代不再推荐用于新项目的功能 但为了向后兼容而保留。引用后一种弃用形式的一种非正式方式是称其为“软”,我已经相应地更新了脚注。

以上是关于以编程方式读取在控制台窗口中选择的当前文本的主要内容,如果未能解决你的问题,请参考以下文章

以编程方式在纵向视图中显示根控制器弹出窗口

以编程方式打开和关闭控制台

C语言控制台窗口图形界面编程:文本移动

Chrome 开发工具控制台 - 以编程方式选择框架

在没有 BHO 的情况下以编程方式确定 IE 窗口当前 URL

在iOS中选择单元格时如何以编程方式更改原型单元格中的标签文本颜色和图像