Have you ever wanted to send text directly to Notepad, without having to use a file?

Typically, you would need to write the text to a file, then open Notepad and instruct it to load the file. There is also a more exotic way: communicate with Notepad via Windows messages, and beam text right into Notepad. This is what Out-Notepad does:

#requires -Version 2
function Out-Notepad
{
  param
  (
    [Parameter(Mandatory=$true, ValueFromPipeline=$true)]
    [String]
    [AllowEmptyString()] 
    $Text
  )

  begin
  {
    $sb = New-Object System.Text.StringBuilder
  }

  process
  {
    $null = $sb.AppendLine($Text)
  }
  end
  {
    $text = $sb.ToString()

    $process = Start-Process notepad -PassThru
    $null = $process.WaitForInputIdle()


    $sig = '
      [DllImport("user32.dll", EntryPoint = "FindWindowEx")]public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
      [DllImport("User32.dll")]public static extern int SendMessage(IntPtr hWnd, int uMsg, int wParam, string lParam);
    '

    $type = Add-Type -MemberDefinition $sig -Name APISendMessage -PassThru
    $hwnd = $process.MainWindowHandle
    [IntPtr]$child = $type::FindWindowEx($hwnd, [IntPtr]::Zero, "Edit", $null)
    $null = $type::SendMessage($child, 0x000C, 0, $text)
  }
}

And this is how you can use it:

 
PS> Get-Service | Out-Notepad

PS> Get-Service | Out-String | Out-Notepad 
 

With both commands, a fresh Notepad instance opens, and all services are written to Notepad. Note the difference, though: the first line produces a list of object names. If you want the objects to be displayed just as rich as they would inside of PowerShell, make sure you pipe them to Out-String before you pipe them to Notepad.

Twitter This Tip! ReTweet this Tip!

Anonymous
  • OK, how and why is this better (for text) than using the native PoSH cmdlets - Clip, Set-Clipboard and Get-Clipboard.

    So, though your example is interesting / usable, this..

    "Typically, you would need to write the text to a file, then open Notepad and instruct it to load the file. "

    ... is not really a valid statement

        # Example, no separate file write / load needed
        Notepad
        Get-Service | Clip
        ## .NET:
        [void][reflection.assembly]::loadwithpartialname("system.windows.forms")
        [system.windows.forms.sendkeys]::sendwait('^v')

    and is this post not a combined repeat of these two...

        'community.idera.com/powershell/powertips/b/tips/posts/send-text-to-notepad'
        'community.idera.com/powershell/powertips/b/tips/posts/sending-objects-to-notepad'

    ...not necessarily that there's anything wrong with that, as another view of an approach is still a good thing.