{"id":53,"date":"2014-09-08T07:00:00","date_gmt":"2014-09-08T07:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2014\/09\/08\/piping-to-notepad\/"},"modified":"2014-09-08T07:00:00","modified_gmt":"2014-09-08T07:00:00","slug":"piping-to-notepad","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20140908-00\/?p=53","title":{"rendered":"Piping to notepad"},"content":{"rendered":"<p>\nIn honor of\n<a HREF=\"http:\/\/notepadconf.com\/\">NotepadConf<\/a>&#8216;s\nnew\n<a HREF=\"https:\/\/www.kickstarter.com\/projects\/1203633826\/notepad-conf\">\nKickStarter video<\/a>,\ntoday&#8217;s Little Program\ntakes its stdin and puts it in a Notepad window.\n<\/p>\n<pre>\nusing System;\nusing System.Diagnostics;\nusing System.Windows.Automation;\nusing System.Runtime.InteropServices;\nclass Program\n{\n  static void Main(string[] args)\n  {\n    \/\/ Slurp stdin into a string.\n    var everything = Console.In.ReadToEnd();\n    \/\/ Fire up a brand new Notepad.\n    var process = new Process();\n    process.StartInfo.UseShellExecute = false;\n    process.StartInfo.FileName = @\"C:\\Windows\\System32\\notepad.exe\";\n    process.Start();\n    process.WaitForInputIdle();\n    \/\/ Find the Notepad edit control.\n    var edit = AutomationElement.FromHandle(process.MainWindowHandle)\n        .FindFirst(TreeScope.Subtree,\n                   new PropertyCondition(\n                       AutomationElement.ControlTypeProperty,\n                       ControlType.Document));\n    \/\/ Shove the text into that window.\n    var nativeHandle = new IntPtr((int)edit.GetCurrentPropertyValue(\n                      AutomationElement.NativeWindowHandleProperty));\n    SendMessage(nativeHandle, WM_SETTEXT, IntPtr.Zero, everything);\n  }\n  [DllImport(\"user32.dll\", EntryPoint=\"SendMessage\", <a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2014\/08\/12\/10549258.aspx\">CharSet=CharSet.Unicode<\/a>)]\n  static extern IntPtr SendMessage(\n    IntPtr windowHandle, int message, IntPtr wParam, string text);\n  const int WM_SETTEXT = 0x000C;\n}\n<\/pre>\n<p>\nThe comments pretty much lay out the steps.\nThe part that may not be obvious is the part that\ndeals with UI Automation:\nWe take the main Notepad window,\nthen ask UI Automation to find Document element inside it.\n<\/p>\n<p>\nFrom that element, we extract the window handle,\nthen drop to Win32 and\n<a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2003\/08\/21\/54675.aspx\">\nsend a <code>WM_SET&shy;TEXT<\/code> message<\/a>\nto jam the text into the Notepad window.\n<\/p>\n<p>\nIf you save this program under the name <code>2np<\/code>,\nthen you can do\n<\/p>\n<pre>\ndir | 2np\n<\/pre>\n<p>\nand it will open a Notepad window with a directory listing inside it.\n<\/p>\n<p>\nChange one line of code, and this program will launch Wordpad\ninstead.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In honor of NotepadConf&#8216;s new KickStarter video, today&#8217;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 [&hellip;]<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-53","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>In honor of NotepadConf&#8216;s new KickStarter video, today&#8217;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 [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/53","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=53"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/53\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=53"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=53"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=53"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}