PowerShell In GUI Blog

PowerShell GUI Box Just In A Few Clicks

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.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: