Pretty up those GUI scripts (2 of 2)

Posted: August 9, 2017 in Powershell, Scripting, Uncategorized
Tags: , , ,

In the last post, I ran through a function to convert an icon file into a here string for use in a script..  This lets you create in memory icons suitable for use in a GUI created through Powershell. In this post, I’m going to show the function to take that Base64 string, and turn it into an icon in memory, that you can then use as a graphical element in your form. The primary driver for doing this is so that you can distribute your script, with graphical elements intact and have the script be the only file sent.

And to give proper credit, most of this function came from https://adminscache.wordpress.com/2013/06/09/base64-encoding-of-images/.  He had a different purpose for this capability, but it paid off for me.

This function is called Get-IconFromBase64.  The first few lines are pretty much boilerplate:


function Get-IconFromBase64{
param(
[Parameter(Mandatory = $true,HelpMessage='The string to be converted to an in-memory icon', ValueFromPipelineByPropertyName = $true, ValueFromPipeline = $true)]
[string]$Base64String
)

We’re setting up the function, and asking for a single parameter which is the icon as a Base64 encoded string as covered in part 1 of this post.

Now for the meat & potatoes 🙂  We add the System.Drawing assembly.  Way back in the day, most scripters used the [reflection.assembly]::LoadWithPartialName() construct, since none of us wanted to look up or remember the fully qualified path with the tokens etc. for a formal load.  Microsoft has been threatening to deprecated this functionality, but fortunately, you can use Add-Type to load the assembly and it works perfectly.

Add-Type -AssemblyName System.Drawing

This next line is an interesting combination – we use the built in [system.convert] assembly to read in the Base64 string and cast that as a memory stream.

$iconStream = [System.IO.MemoryStream][System.Convert]::FromBase64String($Base64String)

Now, we take that memory stream, and convert it to a bitmap.  The System.Drawing assembly provides a function to read in the image from a memory stream, and we cast it as a bitmap.

$iconBMP = [System.Drawing.Bitmap][System.Drawing.Image]::FromStream($iconStream)

The next step is to get the icon from the bitmap.  Again, we turn back to the System.Drawing assembly, and we use the GetHIcon function from System.Drawing.Bitmap to get a handle to the image.  https://msdn.microsoft.com/en-us/library/system.drawing.bitmap.gethicon(v=vs.110).aspx

$iconHandle = $iconBMP.GetHicon()

And as our second to last step, we take that handle and turn it into an icon.

$icon = [System.Drawing.Icon]::FromHandle($iconHandle)

And now we have an in-memory icon that is completely usable as the icon for buttons, as an image etc.  Here is a small form with a button that uses the drive icon from the first post.  (It doesnt’ *do* anything.. it just shows off the icon).  One important limitation – this function only pulls the 32 x 32 pixel icon.  I am sure there are other ways to pull larger icons, and I am looking into it..

But, anywhere you can use an icon in the script, you can use this technique.

Click here to get a pdf version of the demo script.. The script is long because of the Base64 string, and WordPress didn’t seem happy with it, so the PDF, and for some bizarre reason, WordPress treats text files as a security risk.

Here is a picture of what the sample form looks like using the icon in 2 places.

Show-SampleForm

David F.

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