Enhancing User Interfaces in Windows Scripting Host

Enhancing User Interfaces in Windows Scripting Host

In my last blog post we used Windows Scripting Host (WSH) to create a controlled input interface for users. This is great for situations where the process of starting a published application or a login script requires user input. In that post I briefly discussed using Cascading Style Sheets (CSS) to allow the administrator to customize the user interface’s aesthetics. The user interface at the end of that last post looked like this:

 image1

This shorter two-step post will take the script created in the last post and add new functions to it to achieve our enhanced interface by attaching and configuring a style sheet. If you’re not already familiar with CSS it is a way of centralizing and distributing a consistent look and feel across multiple web pages on a web site. The mechanism for delivery is typically a link/reference to an external style sheet file or an automated insertion process like Server Side Includes or pre-rendering scripting languages like ASP or PHP. For the purposes of the scripting interface used here the DHTML capabilities of the DOM will be used to insert our style sheet into the HEAD of the document.

Function #1 – Detecting the Internet Explorer Version

Right from the start there is a concern with the version of the web browser the user’s system is running. It turns out that when moving from Internet Explorer 9 to version 10 Microsoft discontinued the use of the cssText property of the style sheet element, instead opting to use the innerText property for all current and future browsers. This sort of behavior is actually just one small example of the challenging world created by web browser upgrades.

So the first function that needs to be written will determine if the local system is running Internet Explorer 10 or later. This function will return a Boolean based on the version of Internet Explorer detected in the HKEY_LOCAL_MACHINE hive of the Windows registry.

VBscript:

Function isInternetExplorerTenOrLater()
On Error Resume Next
Set wshShell = WScript.CreateObject(“WScript.Shell”)
strValue = wshShell.RegRead(“HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Version”)
If err.number 0 Then
isInternetExplorerTenOrLater = False
On Error Goto 0
Else
If (Split(strValue,”.”)(0) & “.” & Split(strValue,”.”)(1) >= 9.1) Then
isInternetExplorerTenOrLater = True
Else
isInternetExplorerTenOrLater = False
End If
End If
End Function

Jscript:

function isInternetExplorerTenOrLater() {
try {
var wshShell = WScript.CreateObject(“WScript.Shell”);
strValue = wshShell.RegRead(“HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Internet Explorer\\Version”);
if (parseFloat(strValue.split(“.”)[0] + “.” + strValue.split(“.”)[1]) >= 9.1) {
return true;
} else {
return false;
}
} catch(err) {
return false;
}
}

In these functions the browser version is read form the registry key and stored in the variable named strValue. The value as displayed in the registry however is not a simple integer, rather it is collection of four numbers in a dotted decimal form. As an example on this system the version values data is the string 9.11.9600.17207. There is a lot of data in the string that isn’t needed and gets in the way of what the function is trying to accomplish because strings like this cannot be simply compared one to another using conditional operators (<, >, ==, !=). To confuse matters further versions of Internet Explorer 9 or later all start with a 9 as the first integer! In the example given for this system that value represents the browser’s major version is 11. So the conditional operator in this function is comparing a concatenation of the first two integers in dotted decimal form, which is then converted to floating point number and then the conditional is evaluated.

The result is if a browser is found that is version 10 or higher then the function returns true and if the browser is version 9 or older or the registry read fails a false value is returned. With this function’s capability in hand the information needed to create a function that can work on all versions of Internet Explorer is now possible.

Function #2 – Create and Append the Cascading Style Sheet

The createCssData function will start out by creating an enormous string that will be entirety of the style sheet information that will apply changes to each of the HTML elements created in the example script from the last post. This string data is all collected in the strCssText variable to be later fed into either the cssText or innerText attribute of the style sheet. The function will create the style sheet in the DOM, set its attributes, and then append it to the HEAD section of the HTML document.

VBscript:

Function createCssData()
strCssText = “BODY {font-family: Arial; background-color: #FFF} ”
strCssText = strCssText & “BODY {background-image:url(‘http://fqdn.com/folder/image.png’)} ”
strCssText = strCssText & “BODY {background-repeat: no-repeat} ”
strCssText = strCssText & “BODY {background-position: bottom right} ”
strCssText = strCssText & “BUTTON {margin-left: 5px; border-radius: 5px} ”
strCssText = strCssText & “SELECT {padding: 5px; border-radius: 5px} ”
strCssText = strCssText & “SELECT {font-family: Calibri} ”
strCssText = strCssText & “OPTION {font-family: Calibri} ”
strCssText = strCssText & “P {padding: 5px;} ”
Set objStyleSheet = objInternetExplorer.document.createElement(“STYLE”)
objStyleSheet.setAttribute “type”, “text/css”
objInternetExplorer.document.getElementsByTagName(“head”)(0).appendChild(objStyleSheet)
If isInternetExplorerTenOrLater Then
objStyleSheet.innerText = strCssText
Else
objStyleSheet.document.styleSheet(0).cssText = strCssText
End If
End Function

Jscript:

function createCssData() {
strCssText = “BODY {font-family: Arial; background-color: #FFF} “;
strCssText += “BODY {background-image:url(‘http://fqdn.com/folder/image.png’)} “;
strCssText += “BODY {background-repeat: no-repeat} “;
strCssText += “BODY {background-position: bottom right} “;
strCssText += “BUTTON {margin-left: 5px; border-radius: 5px} “;
strCssText += “SELECT {padding: 5px; border-radius: 5px} “;
strCssText += “SELECT {font-family: Calibri} “;
strCssText += “OPTION {font-family: Calibri} “;
strCssText += “P {padding: 5px;} “;
objStyleSheet = objInternetExplorer.document.createElement(‘style’);
objStyleSheet.setAttribute(“type”, “text/css”);
objInternetExplorer.document.getElementsByTagName(‘head’)[0].appendChild(objStyleSheet);          �
if (isInternetExplorerTenOrLater()) {
objStyleSheet.innerText = strCssText;
} else {
objStyleSheet.document.styleSheet[0].cssText = strCssText;
}
}

To better understand what the CSS is doing to our scripted interface I would suggest additional reading here, however it can be entertaining just to alter the settings and see what happens. There is use of some new CSS version three properties that may not render in older web browsers and it will really be up to the administrator on a case-by-case basis to do what works best for their situation. Including these newer properties from version three will not functionally break anything those available feature will just not be rendered. These headaches can be entirely avoided if the script author just leverages the lowest common version of CSS supported by all browsers.

An important step in this function to notice is when the style sheet referenced by the variable objStyleSheet is appended to the HEAD element of the web page. Style sheets that apply dynamically to an entire page need to be place in the head section of the document or the settings will not apply. Individual elements may have their own respective style attributes set inline on the page, but this approach is not preferred as there are more lines of code involved and a consistent look and feel is not easily achieved.

If the function createCssData is called before any other elements are appended the user interface will now display our background image in position, rounded and padded button and drop down list, and different fonts. The resulting image should look like this:

 image2

Bringing It All Together

The end result requires additional coding to accomplish the new aesthetic but the bar to entry is lowered by having the entire scripts available here. These scripts can be quickly copied, modified and pushed out for use. If you have any questions about customization let me know in the comments.

Here are links to the scripts in their entirety saved as txt documents. In these download versions the example URL path for the background image has been replaced with a working path that points to the WMP blogs image you see on this site.

VBscript-UI.vbs
Jscript-UI.js

These scripts will render that image as long as it remains available in that location. If these scripts are used internally facing within an organization it might work best to leverage a web server inside your network like an intranet site. Local files can be loaded by the browser into the script however there are security configuration changes that would need to be made to the web browser and the spirit of this method goes out of its way to avoid these sorts of system reconfigurations.

Your email address will not be published. Required fields are marked *

Phone: 312-602-4000
Email: marketing@westmonroepartners.com
222 W. Adams
Chicago, IL 60606
Show Buttons
Share On Facebook
Share On Twitter
Share on LinkedIn
Hide Buttons