Friday, 7 June 2013

HTA : HTML-defined GUIs for your PowerShell Scripts

In my last posting I showed an HTA containing VBScript, to be called from a batch file or Python script.

This time it's PowerShell's turn, and I've converted to JavaScript - because I've been looking at Node.js and how it has made excellent use of JS's functions being first class objects, closures, etc. Before I carry on studying all that fun, I thought I'd finish up this HTA malarkey first.

Time to run a new script .....
C:\>powershell  c:\testps.ps1

The PowerShell Script : testps.ps1 :

This uses Invoke-Expression twice - first to launch the HTA and wait, and secondly to run a piece of PS code that the HTA will have written to the temp folder (using a cmd line echo!) to set the variables.

A line of JavaScript commands is passed into the HTA call, with | vertical bars taking the place of " quotes. This allows you to run whatever code you like within the HTA.

$htacall = 'cmd /c start /wait mshta.exe "C:\your-path\testps.hta" "^ num1=3.14 ; str1=|String Param| ; alert(|Wow!|)"'
Invoke-Expression -command $htacall

$htacall = 'cmd /c type %TEMP%\'
$outp = Invoke-Expression -command $htacall
Invoke-Expression $outp

"Result: " + $ZZ_NUM1 + " " + $ZZ_STR1


The HTA with JavaScript : testps.hta :

The script in here is explained in the previous blog posting - well, the VBScript version anyway :)

This time (compared to the VBScript version) the variables are initialised in case the HTA is called directly. The BASIC version didn't complain about undeclared variables, but JS will. And I've removed the batch_path stuff, as it's not used here. As always, any comments are welcomed.

<head> <title>My HTA Test</title> <HTA:APPLICATION ID="oHTA" APPLICATIONNAME="HTA Test" SCROLL="no" SINGLEINSTANCE="yes" WINDOWSTATE="maximize" > </head> <SCRIPT LANGUAGE="javascript"> function NoContextMenu(){ alert("Sorry, but right-click is not allowed."); }; function Window_onLoad(){ // Use the following line to disable right-click menu and prevent View Source document.oncontextmenu = new Function ( "NoContextMenu(); return false" ); // Resize to quarter of screen area, centered window.resizeTo(screen.availWidth/2,screen.availHeight/2); window.moveTo(screen.availWidth/4,screen.availHeight/4); // Initialise vars in case the HTA is called without the expected code num1=0; str1=''; // Passed-in code - will execute to set variables var arrParams = oHTA.commandLine.split('^'); for (i = 1; i < arrParams.length; ++i) { // next 2 lines needed for PowerShell method of calling the HTA arrParams[i]=arrParams[i].replace(/"/g,''); // delete any " arrParams[i]=arrParams[i].replace(/\|/g,'"'); // | become " // alert(arrParams[i]); eval(arrParams[i]); } // SCRIPT-specific code : set controls from executed code txt_num1.value=num1; txt_str1.value=str1; }; function Set_Env_Vars(){ // Write PowerShell code (for exec later) to in %TEMP% folder var oWSS = new ActiveXObject(""); strBat='Echo $ZZ_NUM1=' + txt_num1.value + '; $ZZ_STR1="' + txt_str1.value + '" > "%TEMP%"\\';'cmd /C ' + strBat ,0,true); oWSS = null; window.close(); }; window.onload=Window_onLoad; </SCRIPT> <BODY bgcolor="#ccccFF" > <!-- onmousedown = "DisplayMessage" --> <h1>Hello!</h1> Just a little test.... <P> Number &nbsp; <input type="text" value="" name="txt_num1""> <p> String &nbsp; <input type="text" value="" name="txt_str1""> <p> <input type="button" value="Return these to the batch" name="run_button" onClick="Set_Env_Vars()"><p> </BODY>

No comments:

Post a Comment