{"id":8448,"date":"2014-12-15T06:00:44","date_gmt":"2014-12-15T14:00:44","guid":{"rendered":"http:\/\/www.sapien.com\/blog\/?p=8448"},"modified":"2016-05-25T10:59:57","modified_gmt":"2016-05-25T17:59:57","slug":"display-output-in-a-gui-application-copy","status":"publish","type":"post","link":"https:\/\/dev.sapien.com\/blog\/2014\/12\/15\/display-output-in-a-gui-application-copy\/","title":{"rendered":"Displaying Output in a GUI Application"},"content":{"rendered":"<p>After many years of writing scripts for the Windows PowerShell console, I&#8217;m now learning the next level of automation &#8212; writing GUI applications that run Windows PowerShell commands. PowerShell Studio forms provide a gentle and well-guided introduction to GUI applications, but it&#8217;s still taken me some time to break old habits.<\/p>\n<p>I constantly need to remind myself that things that &#8220;just work&#8221; in the console don&#8217;t make any sense in a GUI. Writing output is one of them.<\/p>\n<h3>Writing Output to the Console<\/h3>\n<p>When you generate output in the Windows PowerShell console, the output appears as text strings in the console window.<\/p>\n<pre class=\"output\">PS C:&gt; Get-Date\r\nWednesday, December 3, 2014 7:16:38 AM<\/pre>\n<p>Behind the scenes, Windows PowerShell silently appends an <a href=\"http:\/\/go.microsoft.com\/fwlink\/?LinkID=113368\"><b>Out-String<\/b><\/a><b> <\/b>command to the pipeline and sends the results to &#8220;standard output&#8221; (&#8220;stdout&#8221;). The process that hosts Windows PowerShell handles the standard output, almost always by writing the output to the console (host behavior might vary).<\/p>\n<p>So, if you run a cmdlet that returns objects, such as the <b>Get-Process <\/b>cmdlet, (string representations of) the objects appear in the console.<\/p>\n<p>If you format objects, such as by using <b>Format-List<\/b> or <b>Format-Table<\/b>, (string representations of) the formatted objects appear in the console.<\/p>\n<p>If you run <b>Write-Host<\/b> or <b>Write-Output<\/b>, <b>Out-Host<\/b> or <b>Out-String<\/b>, the output strings appears in the console.<\/p>\n<p>And even if you send the output to an alternate output stream by using <b>Write-Warning<\/b>, <b>Write-Verbose<\/b>, or <b>Write-Error<\/b>, by default, the output appears in the console.<\/p>\n<p>But GUI application don&#8217;t have a console. What happens to the output that would otherwise go to the console when there is no console? And, more importantly, how do I manage output without a console?<\/p>\n<h4><\/h4>\n<h3>Where is my output?<\/h3>\n<p>GUI applications, like the cool ones that you write in PowerShell Studio, don&#8217;t have a console. There is no standard output. There is no auto-appended <a href=\"http:\/\/go.microsoft.com\/fwlink\/?LinkID=113368\"><b>Out-String<\/b><\/a>.<\/p>\n<p>So, when you generate output and don&#8217;t save it to a file or a variable, the output is just lost.<\/p>\n<pre class=\"output\">Get-Process | ... &lt;Nowhere&gt; ...<\/pre>\n<p>It&#8217;s like a pitcher throwing a baseball when there&#8217;s no catcher on the field. The ball just falls to the ground and rolls to a stop .. ignored.<\/p>\n<p><a href=\"http:\/\/www.sapien.com\/blog\/wp-content\/uploads\/2014\/12\/clip_image0021.jpg\"><img loading=\"lazy\" decoding=\"async\" style=\"display: inline; border-width: 0px;\" title=\"clip_image002\" src=\"http:\/\/www.sapien.com\/blog\/wp-content\/uploads\/2014\/12\/clip_image002_thumb1.jpg\" alt=\"clip_image002\" width=\"165\" height=\"112\" border=\"0\" \/><\/a><\/p>\n<p>So, in a GUI application, you can&#8217;t just write output and hope for the best. If you want to display cmdlet output or save it, you need to do it explicitly.<\/p>\n<h3>Display output in a text box<\/h3>\n<p>A GUI application is a collection of controls. To display output, you need to assign the output to a control, such as text box, rich text box, or a data grid.<\/p>\n<p>For example, to display the name of the local computer in the console, you run an $env:ComputerName command.<\/p>\n<pre class=\"output\">PS C:&gt; $env:ComputerName\r\nJUNEB-TESTBOX<\/pre>\n<p>When I try the same thing in a GUI application where there is no console, I don&#8217;t see any result at all. In this example, I created a form with a button that, when clicked, runs the $env:ComputerName expression.<\/p>\n<pre lang=\"PowerShell\">$buttonComputerName_Click = {\r\n    <b>$env:ComputerName<\/b>\r\n}<\/pre>\n<p>But, when I click the button, nothing happens, even if I have a console window open.<\/p>\n<p><a href=\"http:\/\/www.sapien.com\/blog\/wp-content\/uploads\/2014\/12\/GetComputerName.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-8450\" src=\"http:\/\/www.sapien.com\/blog\/wp-content\/uploads\/2014\/12\/GetComputerName.png\" alt=\"GetComputerName\" width=\"400\" height=\"251\" srcset=\"https:\/\/dev.sapien.com\/blog\/wp-content\/uploads\/2014\/12\/GetComputerName.png 846w, https:\/\/dev.sapien.com\/blog\/wp-content\/uploads\/2014\/12\/GetComputerName-300x188.png 300w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><\/a><\/p>\n<p>To display the computer name in a GUI application, I add a display control to my form and assign the output of the command to a method of the display control.<\/p>\n<p>For example, I can add a <b>Textbox<\/b> control to the form and use the assignment operator (=) to assign the result of the expression to the <b>Text<\/b> property of the TextBox. Now, when you click the button, you see the output in the TextBox.<\/p>\n<pre lang=\"PowerShell\">$buttonComputerName_Click = {\r\n    $textboxResults.Text = $env:ComputerName\r\n}<\/pre>\n<p>Here&#8217;s the result:<\/p>\n<p><a href=\"http:\/\/www.sapien.com\/blog\/wp-content\/uploads\/2014\/12\/GetComputerName2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-8451\" src=\"http:\/\/www.sapien.com\/blog\/wp-content\/uploads\/2014\/12\/GetComputerName2.png\" alt=\"GetComputerName2\" width=\"400\" height=\"241\" srcset=\"https:\/\/dev.sapien.com\/blog\/wp-content\/uploads\/2014\/12\/GetComputerName2.png 561w, https:\/\/dev.sapien.com\/blog\/wp-content\/uploads\/2014\/12\/GetComputerName2-300x180.png 300w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><\/a><\/p>\n<h3>Display Output in a Different Program<\/h3>\n<p>You can also display the output of commands in objects that are not part of your program. GUI professionals think that this approach is sloppy and not a best practice, but you might find it useful for testing or debugging.<\/p>\n<p>For example, you can pipe the output to the <b>Out-GridView<\/b> cmdlet.<\/p>\n<pre lang=\"PowerShell\">$buttonComputerName_Click = {\r\n    $env:ComputerName | Out-GridView\r\n}<\/pre>\n<p>Here&#8217;s the result:<\/p>\n<p><a href=\"http:\/\/www.sapien.com\/blog\/wp-content\/uploads\/2014\/12\/JuneTestBox.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-8453\" src=\"http:\/\/www.sapien.com\/blog\/wp-content\/uploads\/2014\/12\/JuneTestBox.png\" alt=\"JuneTestBox\" width=\"400\" height=\"167\" srcset=\"https:\/\/dev.sapien.com\/blog\/wp-content\/uploads\/2014\/12\/JuneTestBox.png 586w, https:\/\/dev.sapien.com\/blog\/wp-content\/uploads\/2014\/12\/JuneTestBox-300x125.png 300w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><\/a><\/p>\n<p>You can also write to a file and open the file. These sample commands create a temporary file, write to the file, and then use Notepad to display the file. Again, this makes real programmers cringe, but it works, at least for testing.<\/p>\n<pre lang=\"PowerShell\">$buttonComputerName_Click = {\r\n    $TmpFile = [System.IO.Path]::GetTempFileName\r\n    $env:COMPUTERNAME | Set-Content -Path $TmpFile\r\n    Notepad $TmpFile\r\n}<\/pre>\n<p>Here&#8217;s the result:<\/p>\n<p><a href=\"http:\/\/www.sapien.com\/blog\/wp-content\/uploads\/2014\/12\/JuneTestBox2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-8454\" src=\"http:\/\/www.sapien.com\/blog\/wp-content\/uploads\/2014\/12\/JuneTestBox2.png\" alt=\"JuneTestBox2\" width=\"400\" height=\"143\" srcset=\"https:\/\/dev.sapien.com\/blog\/wp-content\/uploads\/2014\/12\/JuneTestBox2.png 519w, https:\/\/dev.sapien.com\/blog\/wp-content\/uploads\/2014\/12\/JuneTestBox2-300x106.png 300w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><\/a><\/p>\n<h3>Convert to Strings<\/h3>\n<p>Another task you need to manage in a GUI application is converting objects to text strings. Usually, this just means piping your output to an <b>Out<\/b> cmdlet, such as <b>Out-String<\/b>. <b>Out<\/b> cmdlets, including <b>Out-GridView<\/b>, convert objects to string data.<\/p>\n<p>When you write output to the console, Windows PowerShell automatically appends an <b>Out-String<\/b> command to the pipeline. But, there is no console and no automatic <b>Out-String<\/b> in a GUI application.<\/p>\n<p>When you assign non-string objects to a string object or to a control that takes string objects, such as a TextBox, Windows PowerShell calls the toString() method of the object. (In other languages, the assignment would just fail, but it&#8217;s trying to help.) With some objects, such as <b>DateTime<\/b> and <b>ErrorRecord<\/b> objects, toString() works just fine, but, in many cases, it produces odd-looking results.<\/p>\n<p>For example, this command assigns the results of a <b>Get-Process<\/b> command to a text box. Windows PowerShell recognizes that you need text and calls the toString() method of Process objects, but the result is not useful.<\/p>\n<pre lang=\"PowerShell\">$buttonGetProcess_Click = {\r\n    $textboxResults.Text = Get-Process\r\n}<\/pre>\n<p><a href=\"http:\/\/www.sapien.com\/blog\/wp-content\/uploads\/2014\/12\/GetProcess1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-8455\" src=\"http:\/\/www.sapien.com\/blog\/wp-content\/uploads\/2014\/12\/GetProcess1.png\" alt=\"GetProcess1\" width=\"400\" height=\"283\" srcset=\"https:\/\/dev.sapien.com\/blog\/wp-content\/uploads\/2014\/12\/GetProcess1.png 697w, https:\/\/dev.sapien.com\/blog\/wp-content\/uploads\/2014\/12\/GetProcess1-300x212.png 300w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><\/a><\/p>\n<p>To get a string representation of the default process table, pipe the output to the <b>Out-String<\/b> cmdlet and then assign it to the text box.<\/p>\n<pre lang=\"PowerShell\">$buttonGetProcess_Click = {\r\n    $textboxResults.Text = Get-Process | Out-String\r\n}<\/pre>\n<p><a href=\"http:\/\/www.sapien.com\/blog\/wp-content\/uploads\/2014\/12\/GetProcess2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-8456\" src=\"http:\/\/www.sapien.com\/blog\/wp-content\/uploads\/2014\/12\/GetProcess2.png\" alt=\"GetProcess2\" width=\"400\" height=\"282\" srcset=\"https:\/\/dev.sapien.com\/blog\/wp-content\/uploads\/2014\/12\/GetProcess2.png 716w, https:\/\/dev.sapien.com\/blog\/wp-content\/uploads\/2014\/12\/GetProcess2-300x211.png 300w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><\/a><\/p>\n<p><b>TIP<\/b>: To make the output easy to read, set the text box (or rich text box) to use a monospace font. In PowerShell Studio, right click the text box, click <b>Apply Property Set<\/b>, and then click <b>Apply Console Font<\/b>.<\/p>\n<p>Don&#8217;t avoid toString() completely. There are a few objects where the toString() method produces a useful result. <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/system.datetime(v=vs.110).aspx\"><b>DateTime<\/b><\/a> objects are the classic example. The toString() method of a <b>DateTime<\/b> object returns a &#8220;short-date\/long-time&#8221; format string. <b>Out-String<\/b> returns a &#8220;long-date\/long-time&#8221; format.<\/p>\n<pre class=\"output\">PS C:&gt; (Get-Date).ToString()\r\n12\/6\/2014 10:42:24 AM\r\n\r\nPS C:&gt; Get-Date | Out-String\r\nSaturday, December 6, 2014 10:42:37 AM<\/pre>\n<pre lang=\"PowerShell\">#Uses toString()\r\n$buttonGetDate_Click = {\r\n    $textboxDate.Text = Get-Date\r\n}<\/pre>\n<p><a href=\"http:\/\/www.sapien.com\/blog\/wp-content\/uploads\/2014\/12\/GetDate3.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-8457\" src=\"http:\/\/www.sapien.com\/blog\/wp-content\/uploads\/2014\/12\/GetDate3.png\" alt=\"GetDate3\" width=\"400\" height=\"146\" srcset=\"https:\/\/dev.sapien.com\/blog\/wp-content\/uploads\/2014\/12\/GetDate3.png 680w, https:\/\/dev.sapien.com\/blog\/wp-content\/uploads\/2014\/12\/GetDate3-300x109.png 300w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><\/a><\/p>\n<pre lang=\"PowerShell\">#Uses toString()\r\n$buttonGetDate_Click = {\r\n    $textboxDate.Text = Get-Date | Out-String\r\n}<\/pre>\n<p><a href=\"http:\/\/www.sapien.com\/blog\/wp-content\/uploads\/2014\/12\/GetDate2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-8458\" src=\"http:\/\/www.sapien.com\/blog\/wp-content\/uploads\/2014\/12\/GetDate2.png\" alt=\"GetDate2\" width=\"400\" height=\"134\" srcset=\"https:\/\/dev.sapien.com\/blog\/wp-content\/uploads\/2014\/12\/GetDate2.png 765w, https:\/\/dev.sapien.com\/blog\/wp-content\/uploads\/2014\/12\/GetDate2-300x100.png 300w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><\/a><\/p>\n<p>You can also use the <b>Format <\/b>and <b>UFormat<\/b> parameters of the <a href=\"http:\/\/go.microsoft.com\/fwlink\/?LinkID=113313\"><b>Get-Date<\/b><\/a> cmdlet to get a formatted date string in almost any configuration. For example, to get a date in RFC1123 format, use <b>-Format R <\/b>(or &#8220;r&#8221;). No need to pipe to <b>Out-String<\/b> when you use <b>Format<\/b> or <b>UFormat<\/b>, because these parameters force the cmdlet to return a string.<\/p>\n<pre class=\"output\">PS C:&gt; Get-Date -Format R\r\nTue, 09 Dec 2014 10:46:41 GMT<\/pre>\n<p><a href=\"http:\/\/www.sapien.com\/blog\/wp-content\/uploads\/2014\/12\/GetDate1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-8459\" src=\"http:\/\/www.sapien.com\/blog\/wp-content\/uploads\/2014\/12\/GetDate1.png\" alt=\"GetDate1\" width=\"400\" height=\"164\" srcset=\"https:\/\/dev.sapien.com\/blog\/wp-content\/uploads\/2014\/12\/GetDate1.png 757w, https:\/\/dev.sapien.com\/blog\/wp-content\/uploads\/2014\/12\/GetDate1-300x122.png 300w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><\/a><\/p>\n<h3>Converting Formatted Objects<\/h3>\n<p>In the console, <b>Format<\/b> cmdlets, such as <a href=\"http:\/\/go.microsoft.com\/fwlink\/?LinkID=113303\">Format-Table<\/a>, are usually the last element in a pipeline. The output looks great in the console, because Windows PowerShell appends an <b>Out-String<\/b> command to the pipeline before sending it to the console.<\/p>\n<pre class=\"output\">PS C:&gt; Get-HotFix | Format-Table -Property HotFixID, InstalledOn -AutoSize\r\n\r\nHotFixID     InstalledOn\r\n--------     -----------\r\nKB2693643    10\/7\/2014 12:00:00 AM\r\nKB2769299    9\/5\/2014 12:00:00 AM\r\nKB2883200    10\/7\/2013 12:00:00 AM\r\nKB2883684    9\/5\/2014 12:00:00 AM\r\n...<\/pre>\n<p>But, in a GUI application, by default, you get the result of calling the toString() method of the format objects that the Format cmdlets return.<\/p>\n<pre lang=\"PowerShell\">$buttonGetHotfix_Click = {\r\n    $textboxHotFix.Text = Get-HotFix |\r\n    Format-Table -Property HotFixID, InstalledOn -AutoSize\r\n}<\/pre>\n<p><a href=\"http:\/\/www.sapien.com\/blog\/wp-content\/uploads\/2014\/12\/GetHotfix1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-8461\" src=\"http:\/\/www.sapien.com\/blog\/wp-content\/uploads\/2014\/12\/GetHotfix1.png\" alt=\"GetHotfix1\" width=\"400\" height=\"283\" srcset=\"https:\/\/dev.sapien.com\/blog\/wp-content\/uploads\/2014\/12\/GetHotfix1.png 760w, https:\/\/dev.sapien.com\/blog\/wp-content\/uploads\/2014\/12\/GetHotfix1-300x211.png 300w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><\/a><\/p>\n<p>To get a more usable display in your GUI application, pipe the format objects to the <b>Out-String<\/b> cmdlet before assigning them to the Text property of the TextBox.<\/p>\n<pre lang=\"PowerShell\">$buttonGetHotfix_Click = {\r\n    $textboxHotFix.Text = Get-HotFix |\r\n    Format-Table -Property HotFixID, InstalledOn -AutoSize |\r\n    Out-String\r\n}<\/pre>\n<p><a href=\"http:\/\/www.sapien.com\/blog\/wp-content\/uploads\/2014\/12\/GetHotFix2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-8460\" src=\"http:\/\/www.sapien.com\/blog\/wp-content\/uploads\/2014\/12\/GetHotFix2.png\" alt=\"GetHotFix2\" width=\"400\" height=\"225\" srcset=\"https:\/\/dev.sapien.com\/blog\/wp-content\/uploads\/2014\/12\/GetHotFix2.png 739w, https:\/\/dev.sapien.com\/blog\/wp-content\/uploads\/2014\/12\/GetHotFix2-300x168.png 300w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><\/a><\/p>\n<p>That&#8217;s better!<\/p>\n<p>After a while, the task of managing the output display in your GUI applications become as natural as typing a cmdlet name, but while you&#8217;re learning, be sure to test and make sure that all of your output is captured and displayed in a usable format.<\/p>\n<p><em>June Blender is a technology evangelist at SAPIEN Technologies, Inc. You can reach her at <\/em><a href=\"mailto:juneb@sapien.com\"><em>juneb@sapien.com<\/em><\/a><em> or follow her on Twitter at <\/em><a href=\"https:\/\/twitter.com\/juneb_get_help\"><em>@juneb_get_help<\/em><\/a><em>.<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>After many years of writing scripts for the Windows PowerShell console, I&#8217;m now learning the next level of automation &#8212; writing GUI applications that run Windows PowerShell commands. PowerShell Studio forms provide a gentle and well-guided introduction to GUI applications, but it&#8217;s still taken me some time to break old habits. I constantly need to [&hellip;]<\/p>\n","protected":false},"author":31,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[946,703,25],"tags":[1022,934,874],"class_list":["post-8448","post","type-post","status-publish","format-standard","hentry","category-guiprogramming","category-powershell-studio","category-windows-powershell","tag-guiprogramming","tag-juneb","tag-powershell-studio-2014"],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/posts\/8448","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/users\/31"}],"replies":[{"embeddable":true,"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/comments?post=8448"}],"version-history":[{"count":6,"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/posts\/8448\/revisions"}],"predecessor-version":[{"id":12156,"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/posts\/8448\/revisions\/12156"}],"wp:attachment":[{"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/media?parent=8448"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/categories?post=8448"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/tags?post=8448"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}