HTML Host Control

Introduction

HTML HostThe HTML Host control displays an HTML page from a given URL or a local file. The associated HTML page can be static or dynamic by using JavaScript (embedded or external).

This custom control is available only when you configure your project to use EXE User Interface and it is rendered using the native Microsoft WebBrowser object within an ActiveX host window.

Since this control uses the same core engine as the Microsoft Internet Explorer browser installed on the system, it can leverage all its core functionality, like: HTML rendering engine, JavaScript VM, plug-ins, etc.

Caution!The topmost Internet Explorer version used by the control to emulate HTML content is version 7. For compatiblity reasons, Microsoft implemented this limitation in the IWebBrowser2 API we currently use.

Specific Properties

The HTML Host control has the following specific configurable attributes:

  • Source Type - HTML start page location: at a given URL, a file in package or a temporary file;
  • Horizontal Scrollbar - toggle horizontal scrollbar;
  • Vertical Scrollbar - toggle vertical scrollbar;

NoteWhen using a file in package as a start page for the HTML host, the control can only be displayed on the maintenance installation wizard, when the file is actually available on disk or after InstallFiles standard action executes. If you want to display the control in any stage of the installation using a file source, it is recommended that you use temporary files grouped in a folder placed under "Target Computer\Windows Volume\Temporary" (predefined "TempFolder"). During Prepare Dialog only temporary files can be used and you must define the AiFirstTempFiles property into Install Parameters page.

Usage

You can add and customize this control from the Dialog Editor.

The HTML Host control can be used to display a rich user interface that can blend into your installation package by leveraging the power and expressiveness of WebUI (HTML, CSS, JavaScript).

Another usage scenario for an HTML Host control would be to collect user information or installation data and automatically process it on your web server. For example, you can embed a "Sign Up Form" or "Registration Form" directly into your installation package.

An advantage of using a server-side installation form would be that you could remotely control the installation flow by using our powerful JavaScript API to access the Windows Installer session.

Subscribe to Events

In order for the HTML Host control to react to installation session changes or triggers, you can subscribe it to receive such notifications. From the Dialog Editor, select the HTML Host control and navigate to the Subscribed Events tab to configure the supported events.

The following events are supported to define how an HTML Host control will react:

  • ActionText - 'Text' attribute
  • ActionData - 'Text' attribute
  • TimeRemaining - 'TimeRemaining' attribute
  • SetProgress - 'Progress' attribute
  • MsiPropertyChanged - no attribute

TipIn order for these events to work you must implement the corresponding JavaScript functions. It is not enough to simply Subscribe to Events.

TipThe MsiPropertyChanged notification is received automatically and it is not configurable through the Subscribed Events tab.

NoteThe ActionText, ActionData, TimeRemaining and SetProgress events are sent by the installation engine only during the install phase, so they are useful only when configured for a HTML Host control placed on ProgressDlg.

Receive Event Notifications

Receiving the event notification in the HTML Host control requires that you implement the corresponding JavaScript function for each event.

Caution! For each event the function name is the same with the event name.

The EXE UI engine will call the corresponding JavaScript function from your script and pass it the event parameters. The script can be placed inside the HTML file specified in the "URL" field or it can be referenced by the HTML file.

Function Prototypes:

  • function ActionText(aText) - argument is a string that represents the action that is being executed;
  • function ActionData(aData) - argument is a string that represents parameters of the action that is being executed;
  • function TimeRemaining(aTime) - argument is a string that represents the estimated install time remaining;
  • function SetProgress(aCompleted) - argument is a float that represents the percentage of completion of the current action;
  • function MsiPropertyChanged(aProperty) - argument is a string that represents the name of the property that changed its value;
  • function LoadPage() - notification send when the page needs to update its display;
  • function SavePage() - notification send when the page should save its content;
  • function ResetPage() - notification send when the page should display its initial content and discard any modifications made;

Examples:

<script>
  function ActionText(aText)
  {
    document.getElementById('text').innerHTML = aText;
  }
  function ActionData(aData)
  {
    document.getElementById('data').innerHTML = aData;
  }
  function TimeRemaining(aTime)
  {
    document.getElementById('time').innerHTML = aTime;
  }
  function SetProgress(aCompleted)
  {
    document.getElementById('progressbar-value').style.width = aCompleted + '%';
  }
  function MsiPropertyChanged(aProperty)
  {
    // load new value into a text input (Assumes: [Property ID] same as [HTML ElemId])
    document.getElementById(aProperty).value = external.MsiGetProperty(aProperty);
  }
  function LoadPage()
  {
    // load the value into a text input (Assumes: [Property ID] same as [HTML ElemId])
    document.getElementById('MYPROP').value = external.MsiGetProperty('MYPROP');
  }
  function SavePage()
  {
    // save a text input content into a property (Assumes: [Property ID] same as [HTML ElemId])
    external.MsiSetProperty('MYPROP', document.getElementById('MYPROP').value);
  }
  function ResetPage()
  {
  }
</script>
        

JavaScript API: Accessing Windows Installer Session

The Advanced Installer EXE UI engine exposes several customJavaScript APIs for interaction with the active Windows Installer session. These functions allow you to retrieve MSI information from your JavaScript (get a property value, evaluate a condition, expand a MSI Formatted text), as well as control the installation by setting values for existing properties, creating new properties, publishing control events, etc.

TipThese APIs can be accessed at any time from JavaScript, just like you would call your own functions; by using the external keyword you instruct the EXE UI engine to delegate execution to its native handler.

Function Prototypes:

  • external.MsiSetProperty(aPropName, aPropValue)
    - "aPropName" argument is a string that represents the property name;
    - "aPropValue" argument is a string that represents the new property value (this string can be MSI Formatted);
    - no return value;
     
  • external.MsiGetProperty(aPropName)
    - "aPropName" argument is a string that represents the property name;
    - returns a string representing the property value;
     
  • external.MsiEvaluateCondition(aCondition)
    - "aCondition" argument is a string that represents the MSI Condition to evaluate;
    - returns a boolean value representing the evaluation result;
     
  • external.MsiResolveFormatted(aFormattedText)
    - "aFormattedText" argument is a string that represents the MSI Formatted text to resolve/expand;
    - returns a string value representing the resolved/expanded text;
     
  • external.MsiGetBinaryPath(aBinaryId)
    - "aBinaryId" argument is a string that represents the unique ID of the binary project resource for which we want to retrieve the path;
    - returns a string value representing the physical disk path of the requested binary resource (at run-time);
     
  • external.MsiGetBinaryPathIndirect(aPropName)
    - "aPropName" argument is a string that represents a Windows Installer property containing the unique ID of the binary project resource for which we want to retrieve the path;
    - returns a string value representing the physical disk path of the requested binary resource (at run-time);
     
  • external.MsiPublishEvents(aControlName)
    - "aControlName" argument is a string that represents the name of a control from the current dialog (same dialog as this HTML Host); the EXE UI engine will execute all published events registered on that control;
    - no return value;
     
  • external.MessageBox(aText, aTitle, aFlags)
    - "aText" argument is a string that represents the text to be displayed in the native message box (this string can be MSI Formatted);
    - "aTitle" argument is a string that represents the title of the native message box (this string can be MSI Formatted);
    - "aFlags" argument is an integer that represents the configuration attributes of the native message-box;
    - returns an integer that represents the user action (if the function fails, the return value is zero);
    * these flags and return value share the same values with the standard Windows API MessageBox Function;
     
  • external.MsiGetFormattedError(aErrorId, aParam2 ... aParamN)
    - "aErrorId" argument is an int that represents the error key;
    - "aParam2"... "aParamN" arguments are string values that will be used to replace the [2]...[N] references present in the error message;
    - returns a string value representing the formatted error;
     

Examples:

...
<button onclick="external.MsiSetProperty('MY_PROP', 'My application is [ProductName].');">
  Set MSI Property </button>
...
<button onclick="alert( external.MsiGetProperty('MY_PROP') );">
  Show MSI Property </button>
...
<button onclick="alert( external.MsiEvaluateCondition('MY_PROP = "Foo"') );">
  Is MY_PROP = 'Foo' ? </button>
...
<button onclick="alert( external.MsiResolveFormatted('Hello, [LogonUser] !') );">
  Say 'Hello' </button>
...
<script>
  function UpdateBackground(imageBin)
  {
    var backImgPath = "url(file://" + external.MsiGetBinaryPath(imageBin) + ")";
    document.getElementById('background').style.background = backImgPath;
  }
  function UpdateBackgroundIndirect(imageProp)
  {
    var backImgPath = "url(file://" + external.MsiGetBinaryPathIndirect(imageProp) + ")";
    document.getElementById('background').style.background = backImgPath;
  }

  window.onload=function WindowLoad(event) { UpdateBackgroundIndirect('DialogBitmapProp'); }
</script>
...
<button onclick="external.MsiPublishEvents('Next');">
  Jump to Next Dialog </button>
...
<script>
  function WhoAmI()
  {
    var MB_YESNO = 0x4;
    var MB_ICONQUESTION = 0x20;
    var IDYES = 6;
    var IDNO = 7;

    var ret = external.MessageBox('Are you [LogonUser] ?',
                                  'Your Name',
                                  MB_YESNO | MB_ICONQUESTION);
    return (ret == IDYES);
  }
</script>

<button onclick="WhoAmI();"> Who am I ? </button>
...
<button onclick=" if (isNaN('80a')) alert( external.MsiGetFormattedError(2892, 'MyFieldName', '80a') );">
  Not a Number Error </button>
...