PROVISIO DevBlog

Starting the SiteKiosk File Manager from the Start Screen

This time we are going to have a look at how to start the SiteKiosk File Manager directly from the SiteKiosk Start Screen.

First we need to create a local html file that takes care of the task of opening the File Manager. The code for that file can look like this:

<html>
    <script type='text/JScript'>
        //Initializes the SiteKiosk Object Model
		window.external.InitScriptInterface();
		
		//Checks the prerequisites for opening the File Manger
        function OpenMediaWindow()
        {
            try
            {
                //Initializes the payment features of SiteKiosk
				var lk_SiteCash = SiteKiosk.Plugins("SiteCash");
                
				//Checks if payment is in use and handles the opening of the File Manager accordingly
				if (lk_SiteCash == null || lk_SiteCash == undefined || lk_SiteCash.Enabled && !lk_SiteCash.PayApplications || lk_SiteCash.Enabled && lk_SiteCash.AccessStatus || lk_SiteCash.Enabled && lk_SiteCash.CurrentBalance > 0.0 || lk_SiteCash.Enabled && lk_SiteCash.ApplicationPrice == 0.0 || lk_SiteCash.Enabled && lk_SiteCash.AccessStatus || !lk_SiteCash.Enabled)
                {
                    OpenIntWindow();
                }
                else
                {
                    //Payment is active and inpayment is required
					SiteKiosk.Plugins("SiteCash").ShowPaymentInfoDialog(0, "", false);
                }
            }
            catch (e)
            {
                OpenIntWindow();
            }
        }
		
		//Opens the actual File Manager
        function OpenIntWindow()
        {
            //Defines the available Window styles for the File Manager window
			var WS_OVERLAPPED = 0x00000000;
            var WS_MAXIMIZEBOX = 0x00010000;
            var WS_MINIMIZEBOX = 0x00020000;
            var WS_THICKFRAME = 0x00040000;
            var WS_SYSMENU = 0x00080000;
            var WS_BORDER = 0x00800000;
            var WS_CAPTION = 0x00C00000;
            var WS_MAXIMIZE = 0x01000000;
            var WS_MINIMIZE = 0x20000000;
            var WS_POPUP = 0x80000000;
            var WS_OVERLAPPEDWINDOW = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX;
            var WS_EX_TOOLWINDOW = 0x00000080;
			
			//Creates the File Manager window and assigns its settings
            var mediabox = SiteKiosk.SiteKioskUI.CreateHTMLDialog();
            mediabox.URL = SiteKiosk.SiteKioskDirectory + "skins\\public\\Media\\FileManager\\Selector.html";
            mediabox.Styles = 13565952;
            mediabox.Icon = SiteKiosk.SiteKioskDirectory + "skins\\public\\Media\\FileManager\\Img\\Icons\\fms_ico.ico";
            mediabox.Width = screen.width > 800 ? 1024 : 800;
            mediabox.Height = screen.height > 600 ? 700 : 550;
            mediabox.ExStyles = 0;
            mediabox.Border = true;
            mediabox.Type = "FileManagerDlg";
            mediabox.TopMostWindow = true;
            mediabox.CloseOnInput = false;
            mediabox.Parent = SiteKiosk.WindowList.MainWindow.SiteKioskWindow.Window;
            mediabox.ShowDialog();
			
			//Closes this window after the File Manger has been started
            window.close();
        }
    </script>
    <body onload="OpenMediaWindow();">
    <!-- Body is empty as this window is only used to open the File Manager //-->
	</body>
</html>

Just copy and paste the code to an editor and save it as for example as openfilemanager.html. Now place the file in the html subfolder of your SiteKiosk installation folder.

Next it's time to open the SiteKiosk configuration and under Start Page & Browser select the Start Screen. Click on Customize and open the Start Screen editor. Select one of the three templates and create a new web link element. Edit the element to your liking (icon, color, caption, etc.) and link to the newly created file.

The following example of the result used Template 3 with just a single link element to open the File Manager.

Using the Windows Screen Saver to Show Digital Signage Content

Some of our customers have asked us, if they can use the Digital Signage solution that is part of SiteRemote without starting the SiteKiosk application on the client. Instead of SiteKiosk they had the Windows screen saver in mind. A scenario for this would be that a company wants to show non-critical internal information on the desktops of their employees, e.g. information about social events.

The simple answer is: yes, that is possible. Just install SiteKiosk Windows on the client PC and register it with your SiteRemote team. The SiteKiosk installation is required as it contains the Digital Signage and remote management elements required to place and monitor the content on the client PC. Note that you need a SiteRemote license but as long as you don't want to secure the PC by starting the SiteKiosk browser and only use Digital Signage for the Window screen saver you do not need a SiteKiosk license.

On the client computer you need to open the Windows screen saver management and select SiteCaster from the dropdown menu of available screen savers. Set the screen saver time to the desired value.

Under your SiteRemote team you can create the Digital Signage content as usual and then assign it to the registered clients. Every time the Windows screensaver starts, it will display your Digital Signage files.

Note that you can mix these client PCs with others on which you are using SiteKiosk to protect the computer, so you can effortlessly manage both from your SiteRemote team.

Different Ways to Create SiteKiosk Windows and Android Logfile Entries

SiteKiosk logfiles are text files that contain runtime information about SiteKiosk. The logs are stored on the SiteKiosk client by default. If a SiteKiosk client is registered with a SiteRemote Server the log information is also transferred to the server, where it is used for the remote monitoring and management features of SiteRemote. This applies to SiteKiosk Windows (information can be found here) as well as SiteKiosk Android (the logs are under SiteKiosk\Logs on the sdcard of the device).

Besides containing information about SiteKiosk the logs can also be used to include entries from a website or an external application. This way you could for example generate a custom alert on a SiteRemote Server.

There are different ways to create SiteKiosk log entries from an external source, depending on the client, Windows or Android, and the type of the external source, either html code running in the SiteKiosk browser or another application.

In html code you can use the SiteKiosk Object Model, which is available in a Windows version and one for Android (the Android documentation is not publicly available yet but a preliminary version can be obtained by contacting PROVISIO support).

Note that all html examples require that the pages using the code are allowed to use the SiteKiosk Object Model. In the SiteKiosk Windows configuration you can configure this option under Access/Security -> URLs with Script Permission. In SiteKiosk Android you will find the option under Application -> Browser -> Script Permission (if you use another application option the path will vary).

Our first example demonstrates how to write a log message from a web page running in SiteKiosk Android:

<html>
<head>
	<title></title>
	<script src="sitekiosk.min.js"></script>
</head>
	<body>
		<input id="id_write" type="button" value="Write SiteKiosk Android Log Entry" />
	</body>
	<script type="text/javascript">
		siteKiosk.ready(function (){
			document.getElementById("id_write").onclick = function () {writeLog();};
			
			function writeLog(){
				var lk_logfile = siteKiosk.log;
				lk_logfile.log(20,"TEST",0,"A test log message.");
			}
		}());
	</script>
</html>

The sitekiosk.min.js script file that is referenced in the above example can be obtained from PROVISIO support. If you are using SiteKiosk Android 2.4.118 you do not need the external script anymore, instead you can reference the internal script file that is included in the installation:

<script type="text/javascript" src="sk:///siteKiosk/siteKiosk.js"></script>

With the release of SiteKiosk Android 2.5 you have a third option to access the SiteKiosk Object Model, that does not require to link a script file at all:

<script>
	//method to initialize the SK Object Model as of SKA 2.5
	(new Function(_siteKiosk.getSiteKioskObjectModelCode()))();
</script>

The log method that is used to create the log entry has four parameters. The first is the log level, possible values are 0 (verbose), 10 (debug), 20 (info), 30 (warning) and 40 (error). Mostly you will work with either 10, 20 or 30. The second parameter is the facility that triggered the log message. For most log entries this is usually SiteKiosk. If you generate your own log entries you should use your own facility name, you can choose whatever name you want for it (though you should stick to a standard character set ;-)). The next parameter is the log type, you should either use 0, which stands for a generic log message, or choose one above 9000 as the rest is already used by SiteKiosk for internal log messages. The final parameter is the text string of the actual log entry.

The example for SiteKiosk Windows (see below for a script example for the new SiteKiosk Chrome Fullscreen Browser) is similar to the Android example with slight variations due to differences in the two SiteKiosk Object Model versions:

<html>
	<SCRIPT TYPE="text/javascript">
		window.external.InitScriptInterface();
		function WriteToLog()
		{
			SiteKiosk.Logfile.Write(9001,20,"TEST","A test log message.");
		}
	</SCRIPT>
	<body>
		<input type="button" value="WriteToLog" onclick="WriteToLog()">
	</body>
</html>

The method used here is named Write and expects the same parameters as the Android log method, allthough in a different order. Further information can be found here.

Next is a script example for the new SiteKiosk Chrome Fullscreen Browser (available since SiteKiosk 8.91). The Object Model for the Chrome-based SiteKiosk browser is still in the making, but you can already write log messages. As you may note, this script has a lot of similarities with the Android version:

<!DOCTYPE html>
<html>
<head>
	<title></title>
	<script type="text/javascript" src="file://C:/Program Files (x86)/SiteKiosk/SiteKioskNG/assets/siteKiosk/sitekiosk.js"></script>
</head>
	<body>
		<input id="id_note" type="button" value="note" />
		<input id="id_warn" type="button" value="warn" />
		<input id="id_error" type="button" value="error" />
	</body>
	<script type="text/javascript">
		siteKiosk.ready(function (){
			 document.getElementById("id_note").onclick = function () {writeLog('note');};
			 document.getElementById("id_warn").onclick = function () {writeLog('warn');};
			 document.getElementById("id_error").onclick = function () {writeLog('error');};
			
			function writeLog(caseid){
				var lk_logfile = siteKiosk.log;
				
				switch(caseid){
					case "note":
						lk_logfile.info("TEST",0,"A test notification.");
						break;
					case "warn":
						lk_logfile.warn("TEST",0,"A test warning.");
						break;
					case "error":
						lk_logfile.error("TEST",0,"A test error.");
						break;
					default:
						break;
				}
			}
		}());
	</script>
</html>

There are three different methods, info for informational messages, warn for warning messages and error for error messages. They all accept three parameters. The first is a string for the facility that triggered the log message. For most log entries this is usually SiteKiosk. If you generate your own log entries you should use your own facility name, you can choose whatever name you want for it (though you should stick to a standard character set ;-)). The next parameter is the log type, you should either use 0, which stands for a generic log message, or choose one above 9000 as the rest is already used by SiteKiosk for internal log messages. The final parameter is the text string of the actual log entry.

The SiteKiosk Object Model can also be used from other applications to generate log messages, e.g. applications written in C#. SiteKiosk must run in order for the other application to write to the log files and both applications must run under the same user. A C# example that writes to the SiteKiosk logs has a few more lines than the html versions:

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using SiteKioskRuntimeLib;

namespace SKControl
{
    class Program
    {
        [DllImport("ole32.dll", CallingConvention = CallingConvention.StdCall)]
        public static extern int CoGetClassObject(ref Guid rclsid, uint dwClsContext, IntPtr pServerInfo, ref Guid riid, out IntPtr ppv);

        public bool IsSiteKioskActive()
        {

            /*
                returns false, if SiteKiosk is not currently running
                returns true, if SiteKiosk is running
            */


            // initialize GUID's for classes and interfaces
            Guid lr_FactoryGuid = typeof(ISiteKioskFactory).GUID;
            Guid lr_FactoryClass = typeof(SiteKioskFactoryClass).GUID;
            Guid lr_SiteKioskGuid = typeof(ISiteKiosk).GUID;

            ISiteKiosk mk_pSiteKiosk;

            // try to get the ISiteKioskFactory interface of the instance
            // of SiteKioskFactoryClass
            IntPtr lk_FactoryPtr = new IntPtr();
            CoGetClassObject(ref lr_FactoryClass, 4, new IntPtr(), ref lr_FactoryGuid, out lk_FactoryPtr);
            if (lk_FactoryPtr == IntPtr.Zero)
                // SiteKiosk is not running
                return false;

            // convert the received IntPtr to the requested ISiteKioskFactory
            // interface
            ISiteKioskFactory lk_Factory = (ISiteKioskFactory)Marshal.GetObjectForIUnknown(lk_FactoryPtr);

            if (lk_Factory == null)
                return false;

            // call CreateSiteKiosk to get the ISiteKiosk interface of the
            // current instance of SiteKiosk
            IntPtr lk_SiteKioskPtr = new IntPtr();
            lk_Factory.CreateSiteKiosk(ref lr_SiteKioskGuid, out lk_SiteKioskPtr);

            if (lk_SiteKioskPtr == IntPtr.Zero)
                return false;

            // convert the received IntPtr to the requested
            // ISiteKioskFactory interface
            mk_pSiteKiosk = (ISiteKiosk)Marshal.GetObjectForIUnknown(lk_SiteKioskPtr);

            if (mk_pSiteKiosk == null)
                return false;

            // write to the SiteKiosk log file
            ILogfile2 lk_SKLog = (ILogfile2)mk_pSiteKiosk.Logfile;
            lk_SKLog.Write(9001, 20, "TEST", "A test log message from an external application.");

            return true;
        }

        static void Main(string[] args)
        {
            bool lb_ReturnValue = false; //false if SiteKiosk is not running, true if SiteKiosk is running; not used in this example
            
            Program lk_Prog = new Program();
            lb_ReturnValue = lk_Prog.IsSiteKioskActive();
        }
    }
}

As the C# example is basically using the SiteKiosk Windows Object Model the syntax of the Write method is the same as if you would use it in html code. Make sure to read the part about using the SiteKiosk Object Model in C# from the SiteKiosk Object Model documentation. Running the example code from within Visual Studio while SiteKiosk is running and the debug output window is enabled (SiteKiosk Windows configuration -> Logfiles -> Show output window) will give you something like this:

Note that you may need to build your C# application for an x86 target platform rather than any cpu, otherwise it may fail to detect SiteKiosk on a 64-bit system, because SiteKiosk runs as a 32-bit application.

Using the Blackboard to Transfer Machine Information from SiteRemote to SiteKiosk Windows

A team on the remote management solution SiteRemote enables you to manage your SiteKiosk machines by assigning them to folders and tags. You can also assign address information like the location of the machine or the responsible maintenance person. This information can also come in handy on the client machines. For example you may use it to display different content based on the location address or the assignment to a specific folder or tag. This also means, that whenever you change this information on the server you can directly make use of that change on the client.

Let's find out how to get the information from the SiteRemote server. We will use the SiteKiosk Object Model inside an HTML page running in the SiteKiosk Windows browser. The SiteKiosk Object Model provides the ReadBlackboardAsString method. We will use that method to get the name of the SiteRemote team the machine is registered to, the SiteRemote display name of the machine, the folder and tags the machine is associated to and the address information assigned to the machine. For our example the setup lools like this:

The ReadBlackboardAsString method accepts a string as parameter that specifies the requested information (see the Remarks part here for further information) as shown in this example excerpt:

//Get the name of the SiteRemote team the machine is registered with.
document.getElementById("teamname").innerHTML = SiteRemotePlugin.ReadBlackboardAsString('StC.TeamInfo.Name');
//Get the display name of the machine in the SiteRemote team it is registered with.
document.getElementById("machinename").innerHTML = SiteRemotePlugin.ReadBlackboardAsString('StC.MachineInfo.Name');
//Get the folders and tags the machine is part of.
document.getElementById("groupstags").innerHTML = SplitBlackBoardStrings(SiteRemotePlugin.ReadBlackboardAsString('StC.MachineInfo.LocationInTreeview'));
//Get address information for the machine, e.g. location, maintenance contact.
document.getElementById("supportinfo").innerHTML = SplitBlackBoardStrings(SiteRemotePlugin.ReadBlackboardAsString('StC.MachineInfo.SupportInfo'));

The method returns a string with the SiteRemote blackboard information. Be aware that the string is in JSON format. You can either handle it as a normal string, just like in the above example, which is why the information for the group/tag membership and the address information is processed in an additional method (see the full example code below to see the code of that method) that splits the string at every comma. You can also work with the string in JSON format, for which you may need to add additonal script, see the Examples part here for more information.

The full example code we can build around the reading of the SiteRemote blackboard looks like this:

<html>
	<head>
		<title>SiteKiosk Blackboard Example</title>
		
		<style type="text/css">
			div { color:black; font-style:arial; font-size:18px; }
			span { color:red; font-style:arial; font-size:24px; }
		</style>

		<script type="text/javascript">
			window.external.InitScriptInterface();
			
			SiteRemotePlugin = SiteKiosk.Plugins("SiteRemote");
			
			//First check if the machine is registered with SiteRemote.
			if (SiteRemotePlugin.IsRegistered){
				//Registered. Trigger the initial blackboard request. Note: the first request will most likely come back empty.
				ReadSiteRemoteBlackboard();
			}
			else{
				//Not registered. Show message on screen.
				document.getElementById("registered").stlye.display = "none";
				document.getElementById("notregistered").stlye.display = "inline";
			}
			
			function ReadSiteRemoteBlackboard(){
				try{
					//Get the name of the SiteRemote team the machine is registered with.
					document.getElementById("teamname").innerHTML = SiteRemotePlugin.ReadBlackboardAsString('StC.TeamInfo.Name');
					//Get the display name of the machine in the SiteRemote team it is registered with.
					document.getElementById("machinename").innerHTML = SiteRemotePlugin.ReadBlackboardAsString('StC.MachineInfo.Name');
					//Get the folders and tags the machine is part of.
					document.getElementById("groupstags").innerHTML = SplitBlackBoardStrings(SiteRemotePlugin.ReadBlackboardAsString('StC.MachineInfo.LocationInTreeview'));
					//Get address information for the machine, e.g. location, maintenance contact.
					document.getElementById("supportinfo").innerHTML = SplitBlackBoardStrings(SiteRemotePlugin.ReadBlackboardAsString('StC.MachineInfo.SupportInfo'));
				}catch(e){
					//Blackboard information is not yet available, try again in 10 seconds.
					window.setTimeout("ReadSiteRemoteBlackboard()", 10000);
				}
			}
			
			function SplitBlackBoardStrings(blackboardstring){
				//Split the Blackboard string for better readability.
				var blackboardstringelements = blackboardstring.split(",");
				var composedelements = "";
				
				for (var i = 0; i < blackboardstringelements.length; i++){
					composedelements += blackboardstringelements[i] + "<br />";
				}
				
				return composedelements;
			}
		</script>
	</head>
	<body>
		<div id="registered" style="display:inline;">
			This machine is part of the SiteRemote Team <span id="teamname">[Information not yet available. Please wait.]</span> and 
			its display name on the SiteRemote server is <span id="machinename">[Information not yet available. Please wait.]</span>.
			<br /><br />
			The machine is assigned to the following groups and tags:
			<br />
			<span id="groupstags">[Information not yet available. Please wait.]</span>
			<br /><br />
			These addresses are available for the machine:
			<br />
			<span id="supportinfo">[Information not yet available. Please wait.]</span>
		</div>
		<div id="notregistered" style="display:none;">
			This machine is not registered with SiteRemote!
		</div>
	</body>
</html>

If you save the example code as an HTML page and place it in the html subfolder of your SiteKiosk installation and then configure SiteKiosk to use it as a start page you will get output similar to this:

Note that of course this requires that you register your SiteKiosk Windows client with a SiteRemote server and assign tags and address information to it. As you can see above the address information may include empty fields, if those values have not been provided when creating the address information. You can sort through those with standard Javascript string handling procedures.

For further reading you may want to have a look at the AttachBlackboardListener and DetachBlackboardListener methods, that will enable you to automatically and continously listen for changes to blackboard information on the SiteRemote server, so that the client can immediately react to those changes.

How to Create a Chromium-based Fullscreen Browser in SiteKiosk 8.9

In SiteKiosk 8.9 we introduced a Chromium-based browser engine for rendering content. In that version of SiteKiosk the engine is limited to the Start Screen start page skin. Full Chromium browser engine support is planed for SiteKiosk 9.0 coming in 2015, therefore the follwing instructions only apply to SiteKiosk 8.9.

Using Chromium will enhance the browser experience which is evident in the new Start Screen start page skin. With a few lines of code you can convert the Start Screen into a fullscreen browser to for example make use of the enhanced touch screen features for you own web page. This can be useful for an information or self-service kiosk terminal where no browser toolbar is required. Here are the required steps:

1) Install SiteKiosk 8.9.
2) Start the configuration editor and switch to the Start Page & Browser options.
3) Choose the new Start Screen and press the Customize button.
4) Open the configuration editor of the Start Screen from the next dialog.
5) Choose Template 3 in the dropdown at the top of the editor.
6) Click on the Settings button in the toolbar of the editor.
7) Switch to the Background page and select HTML instead of the default Video selection.
Add the following HTML code:

<script>
window.top.document.location = "http://www.google.de/";
</script>

The URL can of course be replaced by whatever you prefer. You may change the background color if you like at the top of the Background options page. Accept the changes by pressing the OK button.
8) Save the settings in the Start Screen editor.
9) Save the SiteKiosk configuration.
10) Start SiteKiosk.

Now your website is displayed in fullscreen mode in the new Chromium-based browser engine of SiteKiosk 8.9.

Please note the there are a number of limitations as the current use of the Chromium engine in SiteKiosk 8.9 is only intended for the Start Screen. For example there are no error pages if you surf to a non-existent page, you will then see just a blank page. So make sure you test this customization thoroughly in case you actually plan to deploy it.

Changing Individual SiteKiosk Configuration Elements with a SiteRemote Job

Often you just need to change a single SiteKiosk configuration setting. Even when using a great number of SiteKiosk machines this is not a problem, you can just use the configuration feature of SiteRemote to distribute the changed configuration file to the machines.

But what if your machines all use configurations that differ in parts, for example the configurations are all using a different start page to reflect their individual locations while the rest of the settings are the same. This challenge can be solved by making use of the fact that the SiteKiosk configuration files are built on the XML format. This enables you to create a Javascript file that can access and edit a specific element of the configuration file.

The following script examples do not use the SiteKiosk Object Model. They use common Javascript/JScript techniques as described for example in the Microsoft MSDN library.

The first example will enable the fullscreen mode of SiteKiosk. The script starts by creating the required ActiveX objects to access the Windows registry and to edit an XML document. Next it queries the path of the latest SiteKiosk configuration file from the registry, either of a 32 or a 64 bit system. It then loads the document and assigns the XML node for the fullscreen setting and changes its text. Finally the edited configuration file is being saved. For further information on the methods to work with an XML document see http://msdn.microsoft.com/en-us/library/System.Xml.XmlDocument_methods%28v=vs.110%29.aspx.

try{
	//Wsh Shell Object
	var WshShell = new ActiveXObject("WScript.Shell");

	//XML support
	var xmlDoc = new ActiveXObject("Msxml2.DOMDocument.3.0");

	//Path to the SiteKiosk configuration
	var OsType = WshShell.RegRead("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment\\PROCESSOR_ARCHITECTURE");
	if (OsType == "x86")
		var gstr_configpath = WshShell.RegRead("HKEY_LOCAL_MACHINE\\SOFTWARE\\PROVISIO\\SiteKiosk\\LastCfg"); //you may use an absolute path instead, e.g.: var gstr_configpath = "c:\\program files\\sitekiosk\\config\\myconfig.skcfg"
	else
		var gstr_configpath = WshShell.RegRead("HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\PROVISIO\\SiteKiosk\\LastCfg"); //you may use an absolute path instead, e.g.: var gstr_configpath = "c:\\program files\\sitekiosk\\config\\myconfig.skcfg"

	if(xmlDoc.load(gstr_configpath)){
		var lk_nodeselection = xmlDoc.documentElement.selectSingleNode("//sitekiosk-configuration/browserbar/hidemode");
		//Changes the node text to 1 which enables permanent fullscreen mode (0 disables fullscreen, 2 enables fullscreen mode for specific URLs only).
		lk_nodeselection.text = "1";
		//Saves the  changes
		xmlDoc.save(gstr_configpath);
	}
	else{
		//Returns an error exit code to SiteRemote 
		ExitResult.Code = 1;
		ExitResult.Description = "Error opening configuration file.";
	}
}
catch(e){
	try	{
		if(e.number != 0)
			ExitResult.Code = e.number;
		else
			ExitResult.Code = 1;
		ExitResult.Description = e.description;
	}
	catch(e){}
}

After running the script the fullscreen setting of the SiteKiosk configuration looks like this:

The second example adds a URL excluded from filtering to the Content Filter of SiteKiosk. Again it starts by creating the required ActiveX objects and finding the path to the latest SiteKiosk configuration file. Next it adds a new XML node to an existing one for the URL that should be excluded from filtering. After that the document is being saved. For further information on the methods to work with an XML document see http://msdn.microsoft.com/en-us/library/System.Xml.XmlDocument_methods%28v=vs.110%29.aspx.

try{
	//Wsh Shell Object
	var WshShell = new ActiveXObject("WScript.Shell");

	//XML support
	var xmlDoc = new ActiveXObject("Msxml2.DOMDocument.3.0");

	//Path to the SiteKiosk configuration
	var OsType = WshShell.RegRead("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment\\PROCESSOR_ARCHITECTURE");
	if (OsType == "x86")
		var gstr_configpath = WshShell.RegRead("HKEY_LOCAL_MACHINE\\SOFTWARE\\PROVISIO\\SiteKiosk\\LastCfg"); //you may use an absolute path instead, e.g.: var gstr_configpath = "c:\\program files\\sitekiosk\\config\\myconfig.skcfg"
	else
		var gstr_configpath = WshShell.RegRead("HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\PROVISIO\\SiteKiosk\\LastCfg"); //you may use an absolute path instead, e.g.: var gstr_configpath = "c:\\program files\\sitekiosk\\config\\myconfig.skcfg"

	if (xmlDoc.load(gstr_configpath)){
		var lobj_snglnode = xmlDoc.selectSingleNode("//plugin[@name='SiteCoach']");
		var lobj_newelelement,lstr_newtext;
		lobj_newelelement=xmlDoc.createNode(1, "exclude", lobj_snglnode.namespaceURI);
		lstr_newtext=xmlDoc.createTextNode("http://www.provisio.com");
		lobj_newelelement.appendChild(lstr_newtext);
		lobj_snglnode.appendChild(lobj_newelelement);
		//Saves the  changes
		xmlDoc.save(gstr_configpath);
	}
	else{
		//Returns an error exit code to SiteRemote 
		ExitResult.Code = 1;
		ExitResult.Description = "Error opening configuration file.";
	}
}
catch(e){
	try	{
		if(e.number != 0)
			ExitResult.Code = e.number;
		else
			ExitResult.Code = 1;
		ExitResult.Description = e.description;
	}
	catch(e){}
}

After running the script the Content Filter page of the SiteKiosk configuration looks like this:

To run such a script just go to the Jobs section of SiteRemote and create a new job and select Execute Script as action. Copy and paste the code into the text field and assign the job. Do not activate the checkbox Script requires SiteKiosk Object, as it would run the script within the SiteKiosk user context, who for security reasons does not have the necessary rights to edit the configuration.

Note that you should make changes to the configuration file with care and test them first before applying to a great number of terminals. E.g. writing XML incompatible values to the configuration will make the file unreadable, so SiteKiosk will then load the emergency configuration file instead.

In order to let the new configuration file become the active configuration you need to restart SiteKiosk.

How to Delete HTML5 Web Storage Content

HTML5 Web Storage is intended to store content locally on a PC for longer periods, e.g. for working offline. The web page/web app that stores the content is responsible for deleting it as well, therefore SiteKiosk does not delete Web Storage content by design.

In case you come across a project, where you can't influence the behaviour of a web page that uses Web Storage but need to delete the content nonetheless, you may use the scripting options of SiteKiosk to handle that situation.

The following script makes use of the OnReset and OnScreenSaverBegin events of the SiteKiosk Object Model to trigger deleting the Web Storage content. OnReset fires when a person hits the logout button of SiteKiosk or when a Pay session runs out. OnScreenSaverBegin fires once the screensaver starts. Note that deleting the Web Storage requires a restart of SiteKiosk to also clear the Web Storage content from the currently running instance of the browser. This means that the screensaver will only run for the time we define as the wait time for the content deletion to happen, if we use the OnScreenSaverBegin event. Please consider this fact for your project.

Next we need to wait a few seconds to let SiteKiosk run through the default processes that happen if any of the above events occur. To make SiteKiosk wait, we use the AddDelayedEvent method.

The next step is to actually delete the Web Storage content. For that we use the FileSystemObject of Windows Scripting. Be aware that the location of the folder (C:\Users\[User Name]\AppData\Local\Microsoft\Internet Explorer\DOMStore) that needs to be deleted is user sensitive. Make sure to use the path that is appropriate for the user you run SiteKiosk under. In most cases SiteKiosk will run under the restricted SiteKiosk Windows user, therefore the script we are building uses the path suitable for this environment: C:\Users\SiteKiosk\AppData\Local\Microsoft\Internet Explorer\DOMStore.

The final step is to make a restart of SiteKiosk. Without the restart the current browser instance will still use a cached version of the Web Storage content.

The script looks like this:

//Initializing the events we want to use to delete Web Storage
SiteKiosk.OnReset = WaitBeforeDelete;
SiteKiosk.ScreenSaver.OnScreenSaverBegin = WaitBeforeDelete; //Note that using the screensaver event will basically stop the screensaver from running longer than the wait time defined below, because of the required SiteKiosk restart.

function WaitBeforeDelete()
{
	//Give SiteKiosk some time to run through its default session end/screensaver activation methods
	evtid = SiteKiosk.Scheduler.AddDelayedEvent(5000, DeleteWebStorage);
}

function DeleteWebStorage(eventID)
{  
	try
	{	 
		//Deleting the folder with the help of the FileSystemObject
		var fso = new ActiveXObject("Scripting.FileSystemObject");
 		fso.DeleteFolder("C:\\Users\\SiteKiosk\\AppData\\Local\\Microsoft\\Internet Explorer\\DOMStore", true);
 		SiteKiosk.Logfile.Notification("Deleting the Web Storage content was successful");

		//Required restart to clear the Web Storage from the temporary cache of the current browser instance
		SiteKiosk.Restart();
 	}
	catch (e)
	{
		//Create a SiteKiosk logfile entry in case something goes wrong
		SiteKiosk.Logfile.Notification("There was an error deleting the Web Storage content: " + e.description);
	}
}

Save the script under any name as a javascript file, e.g. DeleteWebStorage.js. Put the file in the ..\SiteKiosk\html folder and then open the SiteKiosk configuration and go to Start Page & Browser, click on Advanced and add the script file as an external script under Execute Script.

If you run the script and monitor the logfiles, a successful deletion of the Web Storage will look like this in the moment of the necessary restart of SiteKiosk:

Using SiteKiosk to Automate Window and Dialog Handling

SiteKiosk Windows allows you to add external applications to be started from within the secure environment that SiteKiosk provides. As an additional security layer, the configuration of SiteKiosk lets you specify the handling of windows and dialogs. Usually this is intended to prevent users from changing settings in an options dialog or making other undesired changes to external applications and operating system settings. To achieve this, SiteKiosk identifies windows and dialogs based on title and/or class. After the identification SiteKiosk sends a Windows Message Command (WM_COMMAND), in most cases this is the WM_CLOSE command, to close the window or dialog directly, but SiteKiosk supports a complete range of commands that can be send.

Little known is the fact that the mechanisms of the windows and dialogs management can also be used to automate processes. For this purpose the different available commands are useful as they allow to not only close a dialog automatically but also to make a window or dialog execute certain actions offered in their specific context.

Let's look at this in more detail with the help of an example. When you are printing a PDF file from within SiteKiosk, you will see the print dialog of the Acrobat Reader, that needs to be confirmed before the actual printing starts. SiteKiosk can auto-confirm this dialog to make printing more convenient for the user. In order for SiteKiosk to auto-confirm the PDF printing we need to open the configuration of SiteKiosk and go to Access/Security, there we select Block system critical windows & dialog boxes and click the Settings button. In the new configuration dialog we click the Add button and create a new treatment rule. We choose to close the window immediately, then we select to send a WM_COMMAND to close the window. As the command we select OK from the dropdown. Now we set the title, which is Print in this case, and the class, which is #32770 in this case (you can use a tool like AutoIT to find the class). All other settings can be left as is.

With these settings SiteKiosk will automatically confirm the PDF print dialog with OK, which triggers the printing of the document. Note that for this example Acrobat Reader XI was used and besides the above window and dialog settings SiteKiosk was configured to allow printing.

Accessing Local Resources from the SiteKiosk Browser

SiteKiosk is a secure web browser, by default it does not allow the use of WScript and similar coding options, that let you access local resources. As part of the requirements of a kiosk project you still may need to access such local resources, e.g. for querying a logged in user or reading/changing a local file or the Windows registry.

By adding an additional security layer, SiteKiosk allows you to execute such code as part of an external script file, that you need to specifically allow in the configuration of SiteKiosk. This script is started togehter with SiteKiosk. You can either execute all the required code just within the external script or you can access the script from a webpage as described in another post.

The first example just reads a registry setting and writes its value to the SiteKiosk log files:

//Wsh Shell Object
var WshShell = new ActiveXObject("WScript.Shell");

//This example reads the type of the operating system
var OsType = WshShell.RegRead("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment\\PROCESSOR_ARCHITECTURE");

//Write the gathered information to the SiteKiosk log file
SiteKiosk.Logfile.Notification("Detected OS type: " + OsType);

Just copy the above code into a .js file with whatever name you like and add it as an external script to test for yourself.

The second example queries the user that SiteKiosk currently runs under on the press of a button in a web page. For that we need two files. The html page, that you can put locally or on a web server, and the external script that runs the code that accesses local resources.

First is the external script that will tell us which local user SiteKiosk is running under:

//Initialize the required WScript object
var WshNetwork = new ActiveXObject("WScript.Network");

//Simple method that returns the user name
function QueryUser(){
	return WshNetwork.UserName;
}

Again, just copy the above code into a .js file with whatever name you like and add it as an external script.

Next is the html code that communicates with the external script. Please have a look at this post for more information on that topic.

<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<title>What user is SiteKiosk running under?</title>
<SCRIPT TYPE="text/javascript">
    //Initializing the SiteKiosk Object Model
    window.external.InitScriptInterface();
     
    function QueryUserExt(){
        //Query the user by using the external script file
        var str_user = SiteKiosk.ScriptDispatch.QueryUser();
		window.alert("User Name: " + str_user);
    }
     
//-->
</script>
<body>
    <input type="button" value="What user is SiteKiosk running under?" onclick="QueryUserExt()">
</body>
</html>

Copy the above code into an .html file that you name to your liking and either place it locally (e.g. in the ..\SiteKiosk\html\ folder) or on a web server. If you are not using the ..\SiteKiosk\html\ folder please make sure that the html file has script allowance in the SiteKiosk configuration.

The result of this little experiment will look similar to this:

Be aware that the code is executed with the user rights of the user you run SiteKiosk under, which may limit you options, e.g. you may only be capable of writing in the HKCU branch of the Windows registry and not in HKLM.

Use SiteKiosk to Accept Payment for any kind of Service

The SiteKiosk Pay version allows you to charge a kiosk user for a variety of basic services right out of the box. You can take a fee for surfing the web, making a download, sending a multimedia email, using an application or printing.

By a little bit of code you can use the payment options of SiteKiosk to allow payment directly at the kiosk for whatever service you desire. This can be for goods in a webshop, concert tickets or even fines, e.g. paying a parking violation ticket. This code can even be added to an existing project to add payment by SiteKiosk as an additional feature. You may then use browser detection to execute the SiteKiosk code only within the SiteKiosk browser.

The following code makes use of the SiteKiosk Object Model. It uses the Dispatch object to access the SiteCashScript.js file that implements the StartPullRequest method that we will be using. The file SiteCashScript.js is loaded automatically when you launch SiteKiosk. So to kick off our request for payment we use the following line:

SiteKiosk.Plugins("SiteCash").Script.Dispatch.StartPullRequest("Text to show in the pullmode dialog that states the reason for requesting payment", 0.5, OnPullRequestCompleted, 30);

The first parameter of the StartPullRequest method is a string that states the reason for requesting payment. It will be displayed in the payment request dialog that is triggered by calling the StartPullRequest method. The second parameter is the amount to be requested. The third parameter is the method that is being called once the pull request completes. The fourth and last parameter is the time in seconds that the request dialog will wait for an inpayment.

When the pull request is complete it will call the method you named as the third parameter. This is how it needs to be added to your code:

function OnPullRequestCompleted(bool_success){
    if (bool_success){
        //your code for a successful payment
	}
	else{
		//your code if the payment failed
	}
}

The parameter passed to the method is a boolean value that states whether the requested amount has been paid or not. Depending on the outcome you can add your own code for either of the two scenarios.

A simple implementation of the above could look like this:

<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<title>Pullmode Example</title>
<SCRIPT TYPE="text/javascript">
    //Initializing the SiteKiosk Object Model
    window.external.InitScriptInterface();
     
    function OnPullRequestCompleted(bool_success){
		if (bool_success){
			document.getElementById("result").innerHTML = "Thank you. The payment was successful.";
		}
		else{
			document.getElementById("result").innerHTML = "Payment has not been made.";
		}
	} 
//-->
</script>
<body>
    Please click the button and pay the requested amount 
	<input type="button" value="Make your payment" onclick="SiteKiosk.Plugins('SiteCash').Script.Dispatch.StartPullRequest('Please make your payment! This service', 0.5, OnPullRequestCompleted, 30); ">
    <br />
    <span id="result"></span>
</body>
</html>

When you use the example in SiteKiosk you will see this:

You can even influence the whole process further by editing the StartPullRequest method. We have learned above that the StartPullRequest method is implemented in the file ..\SiteKiosk\SiteCash\SiteCashScript.js and it can be modified to fit your special requirements, e.g. you can change the design of the payment request dialog.

Please make sure to allow scripting for your HTML pages that you use the SiteKiosk Object Model on. To do so, enter the page and the path to the page in the SiteKiosk configuration under ACCESS-> URLs with script permission.