This article shows how a web application can easily be transformed into a native application. It uses the Internet Explorer, which is not among the best browsers, but often satisfying. In some aspects it’s probably even the best choice.
The article also contains download links to a tool that easily allows you to create standalone applications containing any HTML5 content as internal resource.
Node-Webkit
Although a web application already runs on nearly every platform, it might be desired to run the application in a native-like fashion. This can be achieved in several ways. The most recommended way would be to use node-webkit, which is probably also the most flexible solution.
It’s also possible to use PhoneGap / Cordova for this. However, this either requires Windows 8 or the use of a rather unmaintained spare time project.
These solutions (and most of the other solutions we have reviewed) have in common that the output is seldom a single file and often large in size. For example a node-webkit installation includes at least 7 files, which in total sum up to about 55 MB. For a simple web application this might be overkill.
Cordova (PhoneGap)
The Cordova solution boils down to only one executable (~ 750 kB). However, it is required to ship the web application separately, which increases the chance to mess it up if the user decides to alter/delete files. If this is something you can live with, you can download the precompiled base application from our server. To run this, just copy the ‘www’ folder to the folder containing the Cordova.exe (renaming of the executable is possible).
With the www folder along with the application, the users might easily discover that it’s a web application and start playing around with the source files. Others might abandon the application even without testing, especially some die-hard who might still believe HTML5 + JS isn’t ready yet.
Thus, in order to build an application that truly appears to be a native application it is required to hide the payload and making it confusable identical to any native application and especially those built with Delphi.
Custom Solution
In fact we decided to actually build an application in Delphi that serves the web application internally. The desired solution is one small executable only containing everything necessary to host a simple web application. It’s also desired to have a dead simple build process, that might later be added to the build chain in the IDE.
When we look at the Cordova base application we note that the secret for the small size lies in the fact that it uses the Internet Explorer – opposed to the use of chromium or any other web-kit fork. With recent Windows versions (latest Windows XP, Windows 7, 8 and later) all commonly used HTML5 features should be supported – at least enough to run simple applications.
For the ease of installation, the native host application should contain all required HTML code inside the application. This allows to copy the application by only copying the single executable.
The host application itself should use a TWebBrowser component with some minimum outer logic around. The fact that it can directly host resource files can be used to hide HTML, JS and CSS content. While for a single file (or a few of them) it might be sufficient to host it directly from the resources, it would be nice to have a simple server to host the files internally, especially since the direct resource loading does not support subfolders of any kind.
Packaged Web Application
Looking at all other solutions it’s obvious that we need a manifest file to setup the browser itself. Opposed to write our own format, we decided to pick the W3C standardized format for packaged web application. It uses an XML file (‘config.xml’) to describe the applications. It can be re-used for other applications as well (e.g. used in Tizen).
The content of the ‘config.xml’ is pretty simple and often self explaining. Here’s a short example:
<?xml version="1.0" encoding="UTF-8"?>
<widget xmlns = "http://www.w3.org/ns/widgets"
id = "http://www.smartmobilestudio.com/ExampleWidget"
version = "2.0 Beta"
height = "300"
width = "300"
viewmodes = "windowed">
<name short="Example Widget">
The example Widget!
</name>
<feature name="Server">
<param name="Port" value="8090"/>
</feature>
<preferences name="IE">
<param name="version" value="11"/>
</preferences>
<description>
A sample widget to demonstrate some of the possibilities.
</description>
<author href = "http://www.smartmobilestudio.com/"
email = "support@smartmobilestudio.com">Smart Mobile Studio</author>
<icon src="SmartMS_Icon.ico"/>
<content src="index.html"/>
</widget>
Note the custom extension feature, named ‘Server’, which enables the use of an internal server to host the HTML files. This allows to use files from subdirectories, which otherwise can’t be located.
The ‘viewmodes’ is set to “windowed”, which equals a normal chromed window. The size of this window is specified by ‘width’ and ‘height’. The meta information (description, author & such) are not yet linked to the GUI, but copied into the executable.
The ‘content’ ‘src’ name must be identical to the HTML file that is embedded along the ‘config.xml’ file.
If no ‘config.xml’ file is found, default values should be used. And if no embedded ‘index.html’ is found the ‘index.html’ in the base directory should be used. Otherwise the application is expected to throw an error message before terminating itself.
Reference Implementation
After the prerequisites have been determined a reference implementation has already been created. It is available as open source on GitHub. Based on this code it can be used to extend existing applications by copying the relevant snippets. The project itself relies (only) on DWS and OmniXML.
Compatibility
In order to guarantee a certain compatibility, the browser emulation has to be adjusted (see ‘preferences’ section in ‘config.xml’). However, it is only possible to emulate a browser that is already present. Thus an emulation of IE11 (default) will fail if only IE9 is present on the system. Typically a Smart WebApp also works in older IE browsers, so compatibility even with older OS (like Windows XP or Windows 2000) shouldn’t be a problem, as long as a shim for the Internet Explorer is used. This is as easy as adding
Shims.InternetExplorer
to the uses section.
Embedding Tool
In order to achieve the dead simple build process we decided to create a tool that validates and embeds the HTML5 content into a native application template. In order to make it work, you must at least specify an ‘index.html’ file. In addition, it is recommended to specify a simple ‘config.xml’. Additional files can also easily be added.
Once you have specified your package you can save this as an executable (‘Save as…’). Doing so will trigger a validation process, which might result in (discardable) warnings. The final executable is about 2 MB in size and should run on all modern Windows versions that feature at least the IE9. It can be compressed further by using UPX for an even smaller file size.
Download: zip archive [1.897 kB]
Hi,
just an info …
all the downloads links in the page are broken?
This has now been fixed
The problem using Internet Explorer is that you don’t include it. You don’t control it. And it could break if windows ships a new version.
You should think of (alternatively?) including chromium embedded which is compressed about 10 Megabytes.
You’re absolutely right with what you say, but as stated, this is not about “the” way to go, but *one possible solution*. In fact it is a first preview of what we are working on. Of course a similar solution is possible based on CEF. It can also be based on Mozilla’s Gecko engine, etc.
However, none of the solutions result in a single executable file without further packing (which in fact is rather complex). This might or might not be a requirement, but it’s a way to produce executables in the typical appearance (& size) of other RAD tools.
Nice.
I like the fact that it can be self-packaging.
Why not share the Delphi code of the startup program?
It may be a very good basis for building some dedicated applications, with some logic code in Delphi (e.g. a local database or any customized engine), using SMS/HTML5 for the visual rendering.
Then, the same SMS/HTML5 may be packaged for non Windows platforms (using e.g. PhoneGap), and communicate with the Delphi logic code in RESTful client-server mode, this time.
And I’m quite confident I could be able to create some very small .exe size (e.g. with our LVCL library), much smaller than floated executable size of latest versions of Delphi.
Sharing your code, of just the ” host application itself should use a TWebBrowser component with some minimum outer logic around” would be of great interest!
🙂
update:
I just found out the download link of the source code!
Thanks for sharing!
BTW, you are using DWS2 http.sys web server.
Nice – but why is it mandatory to serve the content via HTTP? Isn’t it possible to use a simple callback, without running a web server locally?
You would need administrator rights to launch the http.sys web server, by the way, at least once, for registering the expected URI. This may be annoying for a simple stand-alone application.
> Nice – but why is it mandatory to serve the content via HTTP? Isn’t it possible to use a
> simple callback, without running a web server locally?
The server is typically deactivated and has to be enabled manually, see
Without this setting, it’s deactivated, except for a simple detection of using a non-flat directory structure.
The latter is in fact a problem since storing the files in the resources means a flat structure. Thus some sort of flattening must take place. Unfortunately, it turned out not to be reliable hooking into the redirection code (didn’t worked as expected with IE11 for example).
If you have code that works reliable feel free to change this. You can also fork this with further improvements related to Synopse code. In fact I also experimented with this myself, but decided to stick with code from the team.
Btw. the code is also meant to be used to migrate larger projects gradually from a native app to a web-app. By changing rather independent forms (in an application) from native code to web code, the look and feel can remain mostly the same, while the code underneath gets ready for the web. But this is subject of a different blog post in the future.