Send Text in Clipboard to Application like Notepad (C# or Powershell)
I want to be able to send the text on the clipboard, in Windows, to an application. For example, I'm working on a text file in notepad, and I want to copy a portion out into a new file..I want to copy it to the clipboard and then use a hotkey to launch an application or powershell script that sends that copied text to a new instance of Notepad.
How can I a开发者_JS百科chieve this in C# or Powershell ?
SOLUTION: Using AutoHotKey
^+c::
Send ^c
Run Notepad
WinWait Untitled - Notepad
WinActivate
Send ^v
return
I have 2 solutions, one that uses PowerShell, the other that uses Autohotkey.
Autohotkey version
I would use this one ;) You define custom key and actions bound to the keys. My file contains this code:
^#n::
Run, Notepad
WinWaitActive Untitled - Notepad2
Send !e
Send p
return
It runs notepad2 and then simulates pressing Alt+E and P. That pastes the string the same way as you would press it by yourself. From some reason I had some problems with 'pressing' Ctrl+V (I don't remember that any more). For more info have a look at Autohotkey's website.
PowerShell version
You need to use an editor like Notepad2. With switch /c
it launches the Notepad2 and pastes the text from clipboard.
To make it more useful I use function tnp
defined like this:
(note that you need to run PowerShell with -sta parameter, otherwise they won't to work propely)
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()
}
With these function you can run something like this:
# gets list of members, opens Notepad2 and pastes the content (members list)
(get-date) | gm | tnp
In other words -- if some info would be returned and formatted to screen, you can get it and paste to notepad.
To get you started, in the excellent PowerShell Community Extensions library there is Get-Clipboard
cmdlet that gets the content's of the current clipboard. From there it's fairly trivial to do whatever you want with the clipboard data, such as:
Get-Clipboard > test.txt; notepad test.txt
Running the above gets the current clipboard contents, sets them into test.txt and then opens test.txt in notepad.
One (hackish) strategy would be:
- Start the process.
- Activate its main window.
- Simulate key-strokes as required.
[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());
}
In the specific case of a text-editor like notepad that accepts a path to a text-file as a command-line argument, you could do something more robust but less flexible:
[STAThread]
static void Main()
{
var tempFilePath = Path.GetTempFileName();
File.WriteAllText(tempFilePath , Clipboard.GetText());
Process.Start("Notepad.exe", tempFilePath);
}
If you end up using AutoHotKey, Add ClipWait to make sure AutoHotKey waits for Windows to actually change the clipboard
^+c::
Send ^c
ClipWait
Run Notepad
WinWait Untitled - Notepad
WinActivate
Send ^v
return
If you only want to use the clipboard as a temporary means to transfer the text (thus not lose what you previously saved in the clipboard), you can add something like the following:
^+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)
精彩评论