我希望能够在 Windows 中将剪贴板上的文本发送到应用程序。例如,我在记事本中处理一个文本文件,我想将一部分复制到一个新文件中。我想将它复制到剪贴板,然后使用热键启动应用程序或发送的 powershell 脚本将文本复制到记事本的新实例。
如何在 C# 或 Powershell 中实现这一点?
解决方案:使用 AutoHotKey
^+c::
Send ^c
Run Notepad
WinWait Untitled - Notepad
WinActivate
Send ^v
return
我希望能够在 Windows 中将剪贴板上的文本发送到应用程序。例如,我在记事本中处理一个文本文件,我想将一部分复制到一个新文件中。我想将它复制到剪贴板,然后使用热键启动应用程序或发送的 powershell 脚本将文本复制到记事本的新实例。
如何在 C# 或 Powershell 中实现这一点?
解决方案:使用 AutoHotKey
^+c::
Send ^c
Run Notepad
WinWait Untitled - Notepad
WinActivate
Send ^v
return
我有 2 个解决方案,一个使用 PowerShell,另一个使用Autohotkey。
自动热键版本
我会使用这个 ;) 您定义自定义键和绑定到键的操作。我的文件包含以下代码:
^#n::
Run, Notepad
WinWaitActive Untitled - Notepad2
Send !e
Send p
return
它运行 notepad2,然后模拟按 Alt+E 和 P。粘贴字符串的方式与您自己按它的方式相同。由于某种原因,我在“按下”Ctrl+V 时遇到了一些问题(我不记得了)。有关更多信息,请查看 Autohotkey 的网站。
PowerShell 版本
您需要使用像Notepad2这样的编辑器。使用 switch/c它启动 Notepad2 并从剪贴板粘贴文本。
为了使它更有用,我使用tnp这样定义的函数:(
请注意,您需要使用 -sta 参数运行 PowerShell,否则它们将无法正常工作)
function tnp {
param(
[Parameter(Mandatory=$true,ValueFromPipeline=$true)]
[object]
$InputObject
)
begin { $objs = @() }
process { $objs += $InputObject }
end {
$old = Get-clipboard # store current value
$objs | out-string -width 1000 | Set-Clipboard
notepad /c
sleep -mil 500
$old | Set-Clipboard # restore the original value
}
}
function Set-Clipboard {
param(
[Parameter(Mandatory=$true,ValueFromPipeline=$true,Position=0)][object]$s
)
begin { $sb = new-object Text.StringBuilder }
process {
$s | % {
if ($sb.Length -gt 0) { $null = $sb.AppendLine(); }
$null = $sb.Append($_)
}
}
end { Add-Type –a system.windows.forms; [windows.forms.clipboard]::SetText($sb.Tostring()) }
}
function Get-Clipboard {
Add-Type –a system.windows.forms
[windows.forms.clipboard]::GetText()
}
使用这些功能,您可以运行如下内容:
# gets list of members, opens Notepad2 and pastes the content (members list)
(get-date) | gm | tnp
换句话说——如果某些信息会被返回并格式化到屏幕上,你可以得到它并粘贴到记事本上。
为了帮助您入门,在出色的PowerShell 社区扩展库中,有一个Get-Clipboardcmdlet 可以获取当前剪贴板的内容。从那里开始,对剪贴板数据做任何你想做的事情都相当简单,例如:
Get-Clipboard > test.txt; notepad test.txt
运行上面的代码获取当前剪贴板内容,将它们设置为 test.txt,然后在记事本中打开 test.txt。
一种(骇人听闻的)策略是:
[DllImport("user32.dll")]
private static extern bool SetForegroundWindow(IntPtr hWnd);
[STAThread]
static void Main()
{
var p = Process.Start("Notepad.exe");
p.WaitForInputIdle();
SetForegroundWindow(p.MainWindowHandle); // this can probably be left out.
SendKeys.SendWait(Clipboard.GetText());
}
在像记事本这样的文本编辑器接受文本文件路径作为命令行参数的特定情况下,您可以做一些更健壮但不太灵活的事情:
[STAThread]
static void Main()
{
var tempFilePath = Path.GetTempFileName();
File.WriteAllText(tempFilePath , Clipboard.GetText());
Process.Start("Notepad.exe", tempFilePath);
}
如果您最终使用 AutoHotKey,请添加ClipWait以确保 AutoHotKey 等待 Windows 实际更改剪贴板
^+c::
Send ^c
ClipWait
Run Notepad
WinWait Untitled - Notepad
WinActivate
Send ^v
return
如果您只想将剪贴板用作传输文本的临时方式(这样不会丢失您之前保存在剪贴板中的内容),您可以添加如下内容:
^+c::
ClipSaved := ClipboardAll ; Save the entire clipboard to a variable of your choice.
Send ^c
ClipWait ; Wait for the clipboard to change
Run Notepad
WinWait Untitled - Notepad
WinActivate
Send ^v
Clipboard := ClipSaved ; Restore the original clipboard.
ClipSaved = ; Free the memory in case the clipboard was very large.
return
Dim temp = System.IO.Path.GetTempFileName()
System.IO.File.WriteAllText(temp, Clipboard.GetText())
Process.Start("Notepad.exe", temp)