Tips and Techniques in Smart-update Enabling Software
By Siva Ramamoorthy
Technology Evangelist This technote provides techniques to tailor a software program so that it can be updated through SmartUpdate.
ABSTRACT
SmartUpdate is a set of technologies that enable software to be installed in a secure manner using the Communicator as a front
end. Although any software can be installed using SmartUpdate, it is ideal for Navigator
plug-ins and Java classes. This document is intended for developers who
wish to distribute their software using SmartUpdate. This TechNote provides
helpful hints to the developer for SmartUpdate-enabling his/her software.
This document assumes a basic familiarity with the process of SmartUpdate
and is intended to provide certain practical tips on the process. Also
a basic knowledge of JavaScript is required to follow the JavaScript code
samples. This document also assumes that the client is running Netscape
Communicator version 4.0 or higher. More information on SmartUpdate and JavaScript can be obtained in the
JavaScript Developer Central area of Netscape's developer site.
BASIC OVERVIEW OF THE PROCESS
To SmartUpdate-enable your software, you must follow a series of general steps:
- Provide a JavaScript install script for your software. You could either write the entire install script in JavaScript or
provide a minimal JavaScript install program which calls an existing native installer.
- Obtain the signing certificates, sign the software and package it into a JAR archive
- Publish the JAR archive on the Internet
The following section offers a few tips on some areas of this process.
TIPS ON
TRIGGERING A JAR INSTALL
A new Java class, Trigger has been defined and can be used with JavaScript for installing software. A well-written
JavaScript installer using the Trigger object can provide a great deal of control on
the install process. This section contains a few hints on using the Trigger
class in a very effective manner. More information on the Trigger
object can be obtained in the Reference
section of the JAR Installation managers guide.
In order to ensure that the appropriate JAR gets executed based on the client's system configuration and to ensure that no
install takes place unless really required, your code should make the following checks before
starting the actual install. A sample JavaScript code which does these checks is also included in this section.
Step 1. Check to see if the client has JavaScript turned on.
Step 2. Check to see if the client has Java enabled his/her browser.
Step 3. Check to see if the JAR Installation Manager has been enabled for the client machine.
Step 4. Check the client's platform to determine the appropriate OS and then send the appropriate JAR.
Step 5. (Optional) If the developer chooses to supply different software for different languages (largely because
of User Interface Elements), check the client's language.
Step 6. Finally if all the conditions are appropriate, update the software using the method ConditionalSoftwareUpdate.
This enables the start of a trigger for a particular version of a component. This ensures
that a update starts only if there is no later version of the software installed in the client version registry.
The following sample code should help clarify these concepts:
<HTML>
<HEAD><BODY>
<SCRIPT LANGUAGE='JavaScript1.2'>
<!-- Hide from other browsers
// Step 1. If the browser doesn't have JavaScript turned on, it will ignore
// the <SCRIPT> tag and generate errors on the other lines. The comment tag makes it
// look like everything in between the comments is just a comment for a
// non-JavaScript browser
document.write ("JavaScript is present and on!");
document.close();
trigger = netscape.softupdate.Trigger;
// Step 2. This checks if the client has Java Enabled his/her client
if (navigator.javaEnabled() ){
// Step 3. Checks to see if the JAR Installation manager has been enabled in
// the client's machine
if (trigger.UpdateEnabled() ) {
version_no = new netscape.softupdate.VersionInfo(4,0,1,0);
// For version 4.0.1
// Step 4. Checks the clients operating system (as appropriate)
if (navigator.platform == "Win32") {
// Step 5. Checks the clients language (as appropriate)
if (navigator.language == "jp") // Japanese
// Step 6. Updates using Conditional Software Update
trigger.ConditionalSoftwareUpdate
("http://www.host.com/myjar_Japanese_Win32.jar",
"plugins/my_company_name",version_no,
trigger.DEFAULT_MODE);
else if (navigator.language == "en") // English
trigger.ConditionalSoftwareUpdate
("http://www.host.com/myjar_English_Win32.jar",
"plugins/my_company_name",version_no,
trigger.DEFAULT_MODE);
}
else if (navigator.platform == "SunOS5.5") {
if (navigator.language == "jp")
trigger.ConditionalSoftwareUpdate
("http://www.host.com/myjar_Japanese_Solaris.jar",
"plugins/my_company_name",version_no,
trigger.DEFAULT_MODE);
else if (navigator.language == "en")
trigger.ConditionalSoftwareUpdate
("http://www.host.com/myjar_English_Solaris.jar",
"plugins/my_company_name",
version_no,
trigger.DEFAULT_MODE);
}
}
}
document.close();
// Stop hiding from other browsers -->
</script>
alert ("You need a Browser which is JavaScript enabled");
// The document.close() call a few lines above ensures that this alert does not
// pop up if it happens to be a JavaScript enabled browser
</head></body>
</html>
Back to Top
INCREMENTAL UPDATES
In some situations if you provide incremental updates (like update from
version 4.0 to version 5.0), it might be useful to check the version number of the installed software. This approach could be useful in situations where the software is huge in size and the updates from one version to another version are relatively smaller. By pointing the user to the appropriate upgrade JAR, the download times can be significantly reduced.
The following sample code will illustrate this concept. In the code sample that follows if the client currently has version below 3.0.0 we do a complete install. If they have versions 3.0.1 and 3.0.0 we provide incremental upgrades to the current version which is 3.0.2
// Creates a version
object for versions 3.0.0, 3.0.1 and 3.0.2 of the software. More
// information about
the VersionInfo class can be obtained at the Reference
section
version3_2 = new netscape.softupdate.VersionInfo (3,0,2,50);
version3_1 = new netscape.softupdate.VersionInfo (3,0,1,25);
version3_0 = new netscape.softupdate.VersionInfo (3,0,0,35);
// Obtained the installed version number
installed_version
= netscape.softupdate.Trigger.GetVersionInfo
("Plugins/My company/my_software");
// Based on the installed
software's version number you can direct the appropriate JAR.
// This approach assumes
that you can provide installers to install from any previous
// version to the current version
// If the installed
version is a null (meaning hasn't been installed) or if it is
// lesser than
version 3.0 do a complete install. Notice the use of the method
// StartSoftwareUpdate
as opposed to ConditionalSoftwareUpdate because we do not want to
// check the currently installed version again
if
(installed_version == null ||
installed_version.compareTo(version3_0)
< 0 )
StartSoftwareUpdate("http://www.host.com/version3_2.jar",
trigger.DEFAULT_MODE);
// Now we check if the
installed version is version 3.0.0
else
if (installed_version.compareTo(version3_1) < 0)
netscape.softupdate.Trigger.ConditionalSoftwareUpdate
("http://www.host.com/my_incrementalv0_to_v2.jar",
"Plugins/My company/my_software",
version3_2, trigger.DEFAULT_MODE);
// Now we check if the
installed version is version 3.0.1
else
if (installed_version.compareTo(version3_2) < 0)
netscape.softupdate.Trigger.ConditionalSoftwareUpdate
("http://www.host.com/my_incrementalv1_to_v2.jar",
"Plugins/My company/my_software",
version3_2, trigger.DEFAULT_MODE);
Back to Top
TIPS
ON REGISTERING THE SOFTWARE
IN THE NETSCAPE CLIENT REGISTRY
The client version registry contains hierarchical representation of
the software registered to be used with the Communicator on the client's
machine. The path name within this hierarchy does not specify where the
software is installed but rather it specifies where information (such as
Version number) about the software resides.
A series of questions can be asked to accurately position the software in the registry.
- Is the software related to Communicator? If the software is related to
Communicator, is it a plug-in or a Java Class? If it is a plug-in use the
relative path for plug-ins, as in "Plugins/Company name/my_software". If
it is a JavaClass use the relative path for Java, as in "Java/Download/Company name/my_software".
- For all other software use the absolute path name and make sure that your
company's name appears in the path. For example "/My Company/Finance/Software"
In either case it is higly recommended that you follow these two conventions:
- Use your company name as part of naming scheme. This will ensure that there are no namespace clashes in the tree.
- Do not use the file name of the software as a node in the registry tree; rather use something more generic like my_software
These concepts can be better explained with some sample code
su = new netscape.softupdate.SoftwareUpdate(this, "My plug-in");
su.StartInstall("Plugins/Company Name/My plug-in", vi,
netscape.softupdate.SoftwareUpdate.su.FULL_INSTALL);
In the constructor SoftwareUpdate( ) the string "My plug-in" is the user prompt string. It just denotes the name of the software in plain and simple English. However the naming for the method StartInstall( ) is a
little more complicated. This call specifies the location in the client version registry to put information about the software and its version number.
For plug-ins the best approach is to use a relative pathname, relative to Netscape's plug-in directory under the standard
Netscape registry tree in the client version registry. For example by using "Plugins/Company Name/My plug-in" we ensure that
- Software information gets stored under the plug-in space. This space in the Client Version Registry under the Netscape tree
is specific to the currently running Communicator. For example if there are two versions of
the Communicator it is possible that we can have two identical plug-in
subtrees under two different trees. This will ensure that we can maintain
differences in the plug-ins for the two different versions of Communicator
if we so desire. If we specify absolute path names like in su.StartInstall("/Company
Name/My plug-in", vi, su.FULL_INSTALL) and if there are multiple Communicator's
installed this plug-in will incorrectly appear to be available to all of
them and this will prevent necessary installs in the future.
- Our plug-in has a path which is unique because we included the company name as part of hierarchy. By specifying the company
name and by placing all the software of that company name under the same hierarchy of the tree,
we also ensure that the tree structured is more nicely organized.
- Also by specifying a generic "My plug-in" as the node of the tree rather than some executable such as my_plug-in.exe we can
ensure that the Triggering script we write can be cross-platform.
Back to top
TIPS
ON ERROR HANDLING IN THE INSTALL PROGRAM
If an error occurs while in the installation process, the normal behavior
is to print a message to the Java Console. This may not be very useful to an average user. A better approach would be
if (err != 0 && ! this.silent)
alert ("Error encountered while installing software");
// "this" is an handle to the JavaScript context in which
the code
// is run. We
display the error only if this.silent is false and hence
// we assure that we dont display an alert in case the user had a
// silent install
In addition more information can be obtained about the error by looking
at the Java Console prompt under the Communicator menu.
Back to Top
WHY USE A JAVASCRIPT TRIGGER?
There are two ways to initiate a SmartUpdate install
DIRECT LINK TO A JAR ARCHIVE
An HTML page can contain a direct link to a JAR archive as in
<A HREF="/old?u=http%3A%2F%2Fdeveloper.iplanet.com%2Fdocs%2Ftechnote%2Fsoftdist%2FmyProgram.jar&y=1999">My Jar File</A>.
When Communicator looks at the JAR file, it recognizes the MIME type
and if it authenticates the digital signature it starts executing the JavaScript
installer within the JAR file. This approach can pose problems where the
client is within a proxy server. Certain proxy servers can cause the MIME
type of a JAR file to get garbled. As a result, the client doesn't start
a SmartUpdate and it offers a dialog requesting input on what to do with
the file of a MIME type it doesn't recognize.
USE JAVASCRIPT
TRIGGER SCRIPT
The software can be installed by having a JavaScript trigger script
explicitly request that software be installed. This script provides the
URL from which the software is to be downloaded. This is the recommended
approach to starting a SmartUpdate of your software. This approach provides
the greatest control over the installation process. The script can determine
the characteristics of the client (such as Operating System etc.) and it
can also start the download at an exact time, such as in response to a
button click. Also, if the client doesn't have JavaScript (either because
of inappropriate version of client or because of preference settings),
this problem would be immediately reported. If the HTML page had a direct
link to a JAR file, the fact that JavaScript hasn't been enabled would
not be noticed until the JavaScript installer with the JAR file starts to execute.
Back to Top
TN-SMUP-01-9707
- Related Readings:
-
Any sample code included above is provided for your use on an "AS IS" basis, under the Netscape License Agreement - Terms of Use