PowerShell In GUI Blog

PowerShell GUI Box Just In A Few Clicks

Archive for May 2011

In response to the comment about using IsePack

with one comment

A recommendation for using PowerShellPack’s IsePack Copy-ColoredAsHtml has been made in the comment to my post. I’m not a big fan of this huge package, but this is worth testing for publishing.

I use the same code copy-pasted from an ISE tab:

cls
#region WordPress posting code test
#this is a test of Powershell code coloring
[string]$stringVar1 = "string 1";
[string]$private:stringVar2 = 'string 2';
[string]$script:stringVar3=
@'
string data
'@
[scriptblock]$global:sb = {{Write-Host scriptblock}.Invoke();};
function
write1{Write-Host $stringVar1;}
function private:write2
{param([string]$str2 = '')
Write-Host $str2;}
function script:write3
#this is a function
{
Write-Host $script:stringVar3;
}
function global:Print-SB
{
<#
.SYNOPSIS
This is a code coloring test.
.DESCRIPTION
This test function represents an advanced Powershell function syntax.

.PARAMETER Param
Demonstrates how a scriptblock can be passed as a reference.

.EXAMPLE
PS C:\> Print-SB ([ref]$sb)
#>
[CmdletBinding()]
param(
[Parameter(Position=0, Mandatory=$true)]
[ref]$Param
)
Begin{}
Process{$Param.Value.Invoke()}
End{}
}
write1
private:write2 $private:stringVar2;
script:write3
Print-SB ([ref]$global:sb)
#endregion WordPress posting code test

Below is the result of IsePack code preparation:

cls            
#region WordPress posting code test            
#this is a test of Powershell code coloring            
[string]$stringVar1 = "string 1";            
[string]$private:stringVar2 = 'string 2';            
[string]$script:stringVar3=            
@' string data '@            
[scriptblock]$global:sb = {{Write-Host scriptblock}.Invoke();};            
function            
write1{Write-Host $stringVar1;}            
function private:write2            
{param([string]$str2 = '')            
Write-Host $str2;}            
function script:write3            
#this is a function            
{            
Write-Host $script:stringVar3;            
}            
function global:Print-SB            
{            
 Print-SB ([ref]$sb) #>            
[CmdletBinding()]            
param(            
[Parameter(Position=0, Mandatory=$true)]            
[ref]$Param            
)            
Begin{}            
Process{$Param.Value.Invoke()}            
End{}            
}            
write1            
private:write2 $private:stringVar2;            
script:write3            
Print-SB ([ref]$global:sb)            
#endregion WordPress posting code test

This looks great and very similar to the hand-made colored code from my post. But who has stolen my advanced function’s comment?! 🙂 All the text between <# and C:\> inclusively erased as a cow licked out.

Written by Alexander Petrovskiy

May 5, 2011 at 6:30 pm

Posted in ISE, Powershell, WordPress

Tagged with

WordPress inspired me with ‘Copy a Post’ tool (StatusStrip + ProgressBar)

leave a comment »

Today’s update announced by WordPress motivated me to add a ProgressBar to the same post that is about a StatusStrip. Why? One of two today’s new features is ‘Copy a Post’. What is it? In spite of the availability of that page, I’ll say a little about blogger’s work.

Usually, the PowerShell (or of any programming environment) blogger needs an idea, a time, a code that will be put out and a description. Also, categories and/or tags to make a post visible throughout the Internet.

WordPress provided such a very simple, even boring feature as a copying of existing post. But imagine that on May, 1st I bought a brand new, lightweight Android 2.2 netbook. A great thing for blogging, skyping and facebooking, it was brought to Finland on 2nd and used on the way to see Google maps. How long did I manage not to write a post? I wrote one today, not a post, but a pleasantry great deal of code. Great under these unusual circumstances as a non-Windows/Linux keyboard layout and lack of habitual tools support.

I used some RDP application (demo with no more one host at a time) to connect to my home Windows 7 with Script Editor and ISE. Some key sequences on an Android’s are not habitual, there aren’t such keys as Insert, Home (to a beginning of text string I mean), Del, all Fs (it’s really pity if you use Far or Unreal Commander). The right shift worked as Tab, the left one went weird from time to time, but the vast majority o code was written on Android’s keyboard!

When I was ready to save me first draft accomplished on an Android device, I noticed these features. How do you think whether I was glad or excited after all that fighting with Android OS? The post will be put out later, maybe tomorrow.

And now, this Copy a Post feature again helps me: I thought that there isn’t a reason not to all System.Windows.Forms.ProgressBar example to the very similar StatusBar code. No doubts, Copy a Post is the first I did.

After this long introduction, let’s turn to a sample. I added a progress bar, three radio buttons, two group boxes (to split up radio buttons to two groups) and added some additional code. Should I add more details? If so, please write request in comments.

I’ll simply describe the functions until questions arrived:

– setStatusStrip used for labels and a bar of the $script:stStrip control

– setProgressBar is the same but for a ProgressBar

– createRadioButton creates radio buttons and adds a handler to enable the user set a style to the StatusStrip and ProgressBar

cls
Set-StrictMode -Version Latest
#region $form1
[System.Windows.Forms.Form]$form1 = New-Object System.Windows.Forms.Form;
$form1.Width = 500;
$form1.Height = 500;
[System.Windows.Forms.Button]$btnDirC = New-Object System.Windows.Forms.Button;
$btnDirC.Text = 'dir c:\';
$btnDirC.Left = 300;
$btnDirC.Top = 100;
$btnDirC.add_Click(([System.EventHandler]$handler =
	{
		processDirC;
	}));
$form1.Controls.Add($btnDirC);
[System.Windows.Forms.GroupBox]$script:groupProgressBar = `
	New-Object System.Windows.Forms.GroupBox;
$script:groupProgressBar.Left = 20;
$script:groupProgressBar.Top = 20;
$script:groupProgressBar.Width = 250;
$script:groupProgressBar.Height = 100;
$script:groupProgressBar.Text = "ProgressBar";
[System.Windows.Forms.GroupBox]$script:groupStatusStrip = `
	New-Object System.Windows.Forms.GroupBox;
$script:groupStatusStrip.Left = 20;
$script:groupStatusStrip.Top = 200;
$script:groupStatusStrip.Width = 250;
$script:groupStatusStrip.Height = 150;
$script:groupStatusStrip.Text = "StatusStrip";
$form1.Controls.AddRange(@($script:groupProgressBar, $script:groupStatusStrip));
function processDirC
{
	[int]$maxNumber = (dir c:\).Length;
	setStatusStrip -OperationName $null `
		-OperationProgress $null `
		-ProgressBarMinimum 1 `
		-ProgressBarMaximum $maxNumber `
		-ProgressBarValue 1;
	setProgressBar -ProgressBarMinimum 1 `
		-ProgressBarMaximum $maxNumber `
		-ProgressBarValue 1;
	[int]$counter = 1;
	dir c:\ | `
		%{
          setStatusStrip -OperationName $_ `
			-OperationProgress "$($counter) of $($maxNumber)" `
			-ProgressBarMinimum $null `
			-ProgressBarMaximum $null `
			-ProgressBarValue $counter;
		  setProgressBar  -ProgressBarMinimum $null `
			-ProgressBarMaximum $null `
			-ProgressBarValue $counter;
          [System.Windows.Forms.Application]::DoEvents();
		  sleep -Milliseconds 500;
		  $counter++;
		  }
}
#endregion $form1
#region StatusBar
$form1.Controls.Add(
	(([System.Windows.Forms.StatusStrip]$script:stStrip = `
	#region StatusBar properties
	New-Object System.Windows.Forms.StatusStrip) `
	| %{#at the bottom of the window
		$script:stStrip.Dock = [System.Windows.Forms.DockStyle]::Bottom;
		$script:stStrip.Anchor = [System.Windows.Forms.AnchorStyles]::Top -bor `
			[System.Windows.Forms.AnchorStyles]::Left;
		#layout style by default
		$script:stStrip.LayoutStyle = [System.Windows.Forms.ToolStripLayoutStyle]::Table;
		#operation name
		[System.Windows.Forms.ToolStripLabel]$script:stStripLabelOperation = `
			New-Object System.Windows.Forms.ToolStripLabel;
		$script:stStripLabelOperation.Text = "Write the operation name here";
		#which item is being processed
		[System.Windows.Forms.ToolStripLabel]$script:stStripLabelProgress = `
			New-Object System.Windows.Forms.ToolStripLabel;
		$script:stStripLabelProgress.Text = "Write the item number here";
		#the progress bar
		[System.Windows.Forms.ToolStripProgressBar]$script:stStripProgressBar = `
			New-Object System.Windows.Forms.ToolStripProgressBar;
		$script:stStrip.Items.AddRange([System.Windows.Forms.ToolStripItem[]]@(
									$script:stStripLabelOperation,
									$script:stStripLabelProgress,
									$script:stStripProgressBar
									));
		$script:stStrip.Name = "stStrip";
		$script:stStrip.AutoSize = $true;
		$script:stStrip.Left = 0;
		$script:stStrip.Visible = $true;
		$script:stStrip.Enabled = $true;
		$script:stStripLabelOperation.Width = 50;
		$script:stStripLabelProgress.Width = 50;
		$script:stStripProgressBar.Width = 50;
		$script:stStripProgressBar.Visible = $false;
	#endregion StatusBar properties
	$script:stStrip;}
)	);
#endregion StatusBar
#region ToolStripLayoutStyle
	#region function createRadioButton
function createRadioButton
{
	param([string]$ControlName,
		  [ref]$Top
		  )
	$rb = $null;
	[System.Windows.Forms.RadioButton]$private:rb = `
		New-Object System.Windows.Forms.RadioButton;
	$private:rb.Name = $ControlName;
	$private:rb.Text = $ControlName;
	$private:rb.Left = 20;
	$private:rb.Top = ($Top.Value += 20);
	$private:rb.Width = 200;
	$private:rb.add_CheckedChanged(([System.EventHandler]$handler =
	{
		param($sender)
		if ($sender.Checked){
			if ($sender.Parent -eq $script:groupStatusStrip)
			{
				$script:stStrip.LayoutStyle = `
					([System.Windows.Forms.ToolStripLayoutStyle]($sender.Name));
			}
			else
			{
				$script:pgBar.Style = `
					([System.Windows.Forms.ProgressBarStyle]($sender.Name));
			}
		}
	}));
	return $private:rb;
}
	#endregion function createRadioButton
[int]$top = 0;
$script:groupStatusStrip.Controls.AddRange(
	[System.Windows.Forms.Control[]]@(
	(createRadioButton ([System.Windows.Forms.ToolStripLayoutStyle]::Flow.ToString()) ([ref]$top)),
	(createRadioButton ([System.Windows.Forms.ToolStripLayoutStyle]::HorizontalStackWithOverflow.ToString()) ([ref]$top)),
	(createRadioButton ([System.Windows.Forms.ToolStripLayoutStyle]::StackWithOverflow.ToString()) ([ref]$top)),
	(createRadioButton ([System.Windows.Forms.ToolStripLayoutStyle]::Table.ToString()) ([ref]$top)),
	(createRadioButton ([System.Windows.Forms.ToolStripLayoutStyle]::VerticalStackWithOverflow.ToString()) ([ref]$top))
	));
$script:groupStatusStrip.Controls[([System.Windows.Forms.ToolStripLayoutStyle]::Table.ToString())].Checked = $true;
#endregion ToolStripLayoutStyle
#region ProgressBarStyle
[int]$top = 0;
$script:groupProgressBar.Controls.AddRange(
	[System.Windows.Forms.Control[]]@(
	(createRadioButton ([System.Windows.Forms.ProgressBarStyle]::Blocks.ToString()) ([ref]$top)),
	(createRadioButton ([System.Windows.Forms.ProgressBarStyle]::Continuous.ToString()) ([ref]$top)),
	(createRadioButton ([System.Windows.Forms.ProgressBarStyle]::Marquee.ToString()) ([ref]$top))
	));
$script:groupProgressBar.Controls[([System.Windows.Forms.ProgressBarStyle]::Blocks.ToString())].Checked = $true;
#endregion ProgressBarStyle
#region function setStatusStrip
function setStatusStrip
{
	param($OperationName = "",
		  $OperationProgress = "",
		  $ProgressBarMinimum = 0,
		  $ProgressBarMaximum = 0,
		  $ProgressBarValue = 0
		  )
		try{$null = $script:stStrip;
			if ($OperationName -ne $null -and `
				$script:stStripLabelOperation -ne $null)
				{
					$script:stStripLabelOperation.Text = $OperationName;
					$script:stStripLabelOperation.Width = 200;
				}
			if ($OperationProgress -ne $null -and `
				$script:stStripLabelProgress -ne $null)
				{
					$script:stStripLabelProgress.Text = $OperationProgress;
					$script:stStripLabelProgress.Width = 100;
				}
			if ($script:stStripProgressBar -ne $null){
				if ($ProgressBarMinimum -ne $null)
					{$script:stStripProgressBar.Minimum = $ProgressBarMinimum;}
				if ($ProgressBarMaximum -ne $null)
					{$script:stStripProgressBar.Maximum = $ProgressBarMaximum;}
				if ($ProgressBarValue -ne $null)
					{$script:stStripProgressBar.Value = $ProgressBarValue;}
				if ($script:stStripProgressBar.Minimum -eq `
					$script:stStripProgressBar.Maximum)
					{$script:stStripProgressBar.Visible = $false;}
				else
					{$script:stStripProgressBar.Visible = $true;}
			}
		}
		catch{}
}
#endregion function setStatusStrip
#region ProgressBar
[System.Windows.Forms.ProgressBar]$script:pgBar = New-Object System.Windows.Forms.ProgressBar;
$script:pgBar.Left = 100;
$script:pgBar.Top = 150;
$script:pgBar.Visible = $true;
$script:pgBar.Minimum = 1;
$form1.Controls.Add($script:pgBar);
	#region function setProgressBar
function setProgressBar
{
	param($ProgressBarMinimum = 0,
		  $ProgressBarMaximum = 0,
		  $ProgressBarValue = 0
		  )
		try{$null = $script:pgBar;
			if ($script:pgBar -ne $null){
				if ($ProgressBarMinimum -ne $null)
					{$script:pgBar.Minimum = $ProgressBarMinimum;}
				if ($ProgressBarMaximum -ne $null)
					{$script:pgBar.Maximum = $ProgressBarMaximum;}
				if ($ProgressBarValue -ne $null)
					{$script:pgBar.Value = $ProgressBarValue;}
				if ($script:pgBar.Minimum -eq `
					$script:pgBar.Maximum)
					{$script:pgBar.Visible = $false;}
				else
					{$script:pgBar.Visible = $true;}
			}
		}
		catch{}
}
	#endregion function setProgressBar
#endregion ProgressBar
$form1.ShowDialog() | Out-Null;

The code is downloadable as a script from here.

A hand-made script-to-form converter (sooner a sample than a tool)

leave a comment »

With eternal love to automation, I began today a small project aiming to help creation of PowerShell GUI forms. This post is the first step, will or won’t I do the next is not clearly even to me.

A year ago I wrote something like this. It was a PropertiesBrowser module/add-on, which I used as the Watches window, typical of any IDE, sometimes. It hasn’t been published, though.

Having today morning an hour or slightly more, I decided to write a post mostly to test the new smartbook I own the third day, but at the same time I caught what I want. A simple form generator.

How should it work? Almost every script produces an output. Strings, numbers, boolean, objects, all what may return a PowerShell code. Why don’t allow the scripter to put it on a form without an effort? Sound like a GUI modeling tool (but looks much more uglyer).

Here it is, the code giving some output and used as a sample:

cls
Set-StrictMode -Version Latest
Import-Module FormGen -Force

[int]$i = 3;
Set-OutputToForm $i
Set-OutputToForm $i -SuppressLabel $true
Set-OutputToForm $i -Description "int"
$f = New-Object System.Windows.Forms.Form
Set-OutputToForm $f;
$a = @("s", "T");
Set-OutputToForm $a $false "Array"
Get-ChildItem | Select-Object -First 3 | %{Set-OutputToForm $_ -Description "fileinfo of $($_.FullName)";}
1..2 | %{Set-OutputToForm $_;}
Get-ChildItem | Select-Object -First 1 | %{Set-OutputToForm $_ -Description "fileinfo of $($_.FullName)" -ControlType 'System.Windows.Forms.ListView';}
Get-ChildItem | Select-Object -First 1 | %{Set-OutputToForm $_ -Description "fileinfo of $($_.FullName)" -ControlType 'System.Windows.Forms.TreeView';}
Get-ChildItem | Select-Object -First 1 | %{Set-OutputToForm $_ -Description "fileinfo of $($_.FullName)" -ControlType 'System.Windows.Forms.ComboBox';}
Show-Result;

As can be seen, there is the FormGen module and two functions exported from it, Set-OutputToForm and Show-Result. While the former adds data to a form still invisible, the latter, to be used once, displays the form.

Set-StrictMode -Version Latest
[int]$script:topPosition = 0;
[System.Windows.Forms.Form]$script:frmMain = `
	New-Object System.Windows.Forms.Form;
$script:frmMain.Width = 500;

function Set-OutputToForm
{
 Set-OutputToForm $data
			PS> 1..10 | %{Set-OutputToForm $_;}
			PS> Get-ChildItem | %{Set-OutputToForm $_ -SuppressLabel $true; $null;}
		.Notes
			Author: Alexander Petrovskiy
	#>
	[CmdletBinding()]
	param([Parameter(Mandatory=$true,ValueFromPipeline=$true)]
    	  [ValidateNotNullOrEmpty()]
		  $InputObject,
		  [bool]$SuppressLabel = $false,
		  [string]$Description = "",
		  [string]$ControlType = ""
		  )
	Begin{}
	Process{
	[bool]$result = $false;
	try{
		if (-not $SuppressLabel)
		{
			[System.Windows.Forms.Label]$private:label = `
				New-Object System.Windows.Forms.Label;
			$script:topPosition += 10;
			$private:label.Top = $script:topPosition;
			$private:label.Left = 50;
            $private:label.Width = $script:frmMain.Width - 50;
            $private:label.Visible = $true;
			if ($Description.Length -gt 0)
			{
				$private:label.Text = $Description;
			}
            else
            {
                $private:label.Text = $InputObject.GetType().ToString();
            }
			$script:frmMain.Controls.Add($private:label);
			$script:topPosition += $private:label.Height;
		}

		[bool]$private:useCustomControl = $false;
		[System.Windows.Forms.Control]$private:ctrl = `
			New-Object System.Windows.Forms.Control;
		if ($ControlType.Length -gt 0)
		{
			try{[System.Windows.Forms.Control]$private:ctrl =
				New-Object $ControlType;
				$private:useCustomControl = $true;
			}catch{$private:useCustomControl = $false;}
		}
		#of which type these data?
		#an array?
		if ($InputObject -is [System.Array])
		{
			if (-not $private:useCustomControl){
				[System.Windows.Forms.ListBox]$private:ctrl = `
					New-Object System.Windows.Forms.ListBox;}
			for($private:i = 0; $private:i -lt $InputObject.Length;
				$private:i++)
			{
				if ($private:ctrl -is [System.Windows.Forms.ListBox] -or `
					$private:ctrl -is [System.Windows.Forms.ComboBox] -or `
					$private:ctrl -is [System.Windows.Forms.ListView]){
						$private:ctrl.Items.Add($InputObject[$private:i]);}
				if ($private:ctrl -is [System.Windows.Forms.TreeView]){
					$private:ctrl.Nodes.Add($InputObject[$private:i]);}
			}
		}
		#a string? int one? other simple type?
		elseif ($InputObject.GetType().BaseType.Name -eq 'ValueType')
		{
			if (-not $private:useCustomControl){
				[System.Windows.Forms.Label]$private:ctrl = `
					New-Object System.Windows.Forms.Label;}
			if ($private:ctrl -is [System.Windows.Forms.ListBox] -or `
				$private:ctrl -is [System.Windows.Forms.ComboBox] -or `
				$private:ctrl -is [System.Windows.Forms.ListView]){
					$private:ctrl.Items.Add($InputObject.ToString());}
			if ($private:ctrl -is [System.Windows.Forms.TreeView]){
				$private:ctrl.Nodes.Add($InputObject.ToString());}
			if ($private:ctrl -is [System.Windows.Forms.Label] -or `
				$private:ctrl -is [System.Windows.Forms.TextBox]){
					$private:ctrl.Text = $InputObject.ToString();}
		}
		else
		{
			if (-not $private:useCustomControl){
				[System.Windows.Forms.PropertyGrid]$private:ctrl = `
					New-Object System.Windows.Forms.PropertyGrid;}
			if ($private:ctrl -is [System.Windows.Forms.PropertyGrid]){
				$private:ctrl.SelectedObject = $InputObject;}
			if ($private:ctrl -is [System.Windows.Forms.ListBox] -or `
				$private:ctrl -is [System.Windows.Forms.ComboBox] -or `
				$private:ctrl -is [System.Windows.Forms.ListView]){
					$private:ctrl.Items.Add($InputObject.ToString());}
			if ($private:ctrl -is [System.Windows.Forms.TreeView]){
				$private:ctrl.Nodes.Add($InputObject.ToString());}
		}
		#common properties
		$private:ctrl.Left = 50;
		$private:ctrl.Top = $script:topPosition;
		$private:ctrl.Visible = $true;
		$script:frmMain.Controls.Add($private:ctrl);
		$script:topPosition += $private:ctrl.Height;
	}catch{}

	$result = $true;
	return $result;}
	End{}
}

function Show-Result
{
	$script:frmMain.Height = $script:topPosition + 40;
	$script:frmMain.ShowDialog() | Out-Null;
}

Export-ModuleMember -Function Set-OutputToForm, Show-Result;

Need to repeat, this is sooner a concept than a ready-to-use tool, so that use it as is. Probably, I’ll update it. The current version attached here.

Although it’s not an advantage for powershellers, I’m proud that at least a half of this code was written on my Android smartbook. This means that I can write from more places than I could before. I have had for two years a netbook, but without 3G and its keyboard was damaged on travel. Gladly, now I can write on the go again, with the actually mobile device.

Design a site like this with WordPress.com
Get started