Created
September 20, 2018 10:33
-
-
Save JohnLBevan/ba1942707374f1c9189484aa294c8db6 to your computer and use it in GitHub Desktop.
Solution to stream output to a running instance of Notepad (or potentially other applications). https://stackoverflow.com/a/52422936/361842
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #requires -Version 2 | |
| #based on Out-Notepad script from http://community.idera.com/powershell/powertips/b/tips/posts/send-text-to-notepad; only amended to allow appending. | |
| function Out-Application { | |
| [CmdletBinding(DefaultParameterSetName = 'ByString')] | |
| Param ( | |
| [Parameter(Mandatory=$true, ValueFromPipeline=$true, ParameterSetName = 'ByString')] | |
| [AllowEmptyString()] | |
| [String]$InputString | |
| , | |
| [Parameter(Mandatory=$true, ValueFromPipeline=$true, ParameterSetName = 'ByObject')] | |
| [AllowEmptyString()] | |
| [PSObject]$InputObject | |
| , | |
| [Parameter(Mandatory=$false, ValueFromPipeline=$false)] | |
| [System.Diagnostics.Process]$TargetApplication = (Start-Process 'notepad' -PassThru) #default the target application to a new instance of notepad | |
| , | |
| [Parameter(Mandatory=$false, ValueFromPipeline=$false)] | |
| [String]$SubWindowName = "Edit" #this is the notepad edit box; for other apps we may want a different class/window name (or this may be completely innappropriate; only really designed for notepad, but with some pieces left flexible in case we can re-use elsewhere) | |
| , | |
| [Parameter(Mandatory=$false, ValueFromPipeline=$false)] | |
| [Switch]$ReturnProcess | |
| , | |
| [Parameter(Mandatory=$false, ValueFromPipeline=$false)] | |
| [Switch]$Flush | |
| ) | |
| begin { | |
| [int]$WM_SETTEXT = 0x000C | |
| [int]$WM_GETTEXTLENGTH = 0x000E | |
| [int]$EM_SETSEL = 0x00B1 | |
| [int]$EM_REPLACESEL = 0x00C2 | |
| [Type]$winApi = 'Microsoft.PowerShell.Commands.AddType.AutoGeneratedTypes.APISendMessage' -as [Type] | |
| if ($winApi -eq $null) { | |
| $winApiImports = ' | |
| [DllImport("user32.dll", EntryPoint = "FindWindowEx")]public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow); | |
| [DllImport("User32.dll", EntryPoint = "SendMessage")]public static extern int SendMessageGetTextLength(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam); | |
| [DllImport("User32.dll", EntryPoint = "SendMessage")]public static extern int SendMessage(IntPtr hWnd, int uMsg, int wParam, string lParam); | |
| ' | |
| $winApi = Add-Type -MemberDefinition $winApiImports -Name APISendMessage -PassThru | |
| } | |
| } | |
| process { | |
| [pscustomobject]$pipelineOutput = [pscustomobject]@{} | |
| if ($PSCmdlet.ParameterSetName -eq 'ByObject') { | |
| $pipelineOutput | Add-Member -MemberType 'NoteProperty' -Name 'InputObject' -Value $InputObject | |
| $InputString = $InputObject | Format-List | Out-String | |
| } else { | |
| $pipelineOutput | Add-Member -MemberType 'NoteProperty' -Name 'InputString' -Value $InputString | |
| } | |
| if ($ReturnProcess) { | |
| $pipelineOutput | Add-Member -MemberType 'NoteProperty' -Name 'TargetApplication' -Value $TargetApplication | |
| } | |
| $TargetApplication.WaitForInputIdle() | Out-Null | |
| $hwnd = $TargetApplication.MainWindowHandle | |
| [IntPtr]$childWindow = $winApi::FindWindowEx($hwnd, [IntPtr]::Zero, $SubWindowName, $null) | |
| if ($Flush) { | |
| #specifying flush removes all content and pastes the new data in its place; useful if you wanted to watch the latest value in notepad without having a historic feed | |
| $winApi::SendMessage($childWindow, $formFeed, [IntPtr]::Zero, $InputString) | Out-Null | |
| } else { | |
| #if not flushing then we append content after existing content | |
| [int]$length = $winApi::SendMessageGetTextLength($childWindow, $WM_GETTEXTLENGTH, [IntPtr]::Zero, [IntPtr]::Zero) | |
| $winApi::SendMessage($childWindow, $EM_SETSEL, $length, $length) | Out-Null | |
| $winApi::SendMessage($childWindow, $EM_REPLACESEL, 1, $InputString) | Out-Null | |
| } | |
| $pipelineOutput | |
| } | |
| } | |
| Clear-Host | |
| $notepad = Get-Process | Out-String | Out-Application -ReturnProcess | Select-Object -ExpandProperty 'TargetApplication' -First 1 | |
| Get-Service | Out-Application -TargetApplication $notepad | Out-Null |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment