Piping to notepad

Raymond Chen

In honor of NotepadConf‘s new KickStarter video, today’s Little Program takes its stdin and puts it in a Notepad window.

using System;
using System.Diagnostics;
using System.Windows.Automation;
using System.Runtime.InteropServices;
class Program
{
  static void Main(string[] args)
  {
    // Slurp stdin into a string.
    var everything = Console.In.ReadToEnd();
    // Fire up a brand new Notepad.
    var process = new Process();
    process.StartInfo.UseShellExecute = false;
    process.StartInfo.FileName = @"C:\Windows\System32\notepad.exe";
    process.Start();
    process.WaitForInputIdle();
    // Find the Notepad edit control.
    var edit = AutomationElement.FromHandle(process.MainWindowHandle)
        .FindFirst(TreeScope.Subtree,
                   new PropertyCondition(
                       AutomationElement.ControlTypeProperty,
                       ControlType.Document));
    // Shove the text into that window.
    var nativeHandle = new IntPtr((int)edit.GetCurrentPropertyValue(
                      AutomationElement.NativeWindowHandleProperty));
    SendMessage(nativeHandle, WM_SETTEXT, IntPtr.Zero, everything);
  }
  [DllImport("user32.dll", EntryPoint="SendMessage", CharSet=CharSet.Unicode)]
  static extern IntPtr SendMessage(
    IntPtr windowHandle, int message, IntPtr wParam, string text);
  const int WM_SETTEXT = 0x000C;
}

The comments pretty much lay out the steps. The part that may not be obvious is the part that deals with UI Automation: We take the main Notepad window, then ask UI Automation to find Document element inside it.

From that element, we extract the window handle, then drop to Win32 and send a WM_SET­TEXT message to jam the text into the Notepad window.

If you save this program under the name 2np, then you can do

dir | 2np

and it will open a Notepad window with a directory listing inside it.

Change one line of code, and this program will launch Wordpad instead.

0 comments

Discussion is closed.

Feedback usabilla icon