Developers, Developers, Developers! Maksim Sorokin IT Blog

8Apr/11Off

IzPack: Installing Only When Version Was Changed

This post describes a concept of updating a product only when a Maven version of it was changed.

Assume you have a product A, installable by IzPack and built by Maven. When you install product A, you may use RegistryInstallerListener to add entry to the registry. In RegistrySpec.xml (where you provide target key where to store information) you use Maven ${project.version} property. Therefore, when the product A will be installed, the Maven version will be stored in the Registry. Next time you install product A you use read that entry from a registry (here I describe how to do that in IzPack 4. This is out-of-the-box in IzPack 5) and then compare the Maven versions (you may use this post information to create a Maven panel) and determine, whereas to install/update a product.

Product A may also be independent installer, launched from another installer. For instance, if product A installer requires administrative rights, and it is included from product B, which doesn' require administrative right, you would like to avoid UAC as much as possible. So from product B you can check version of product A and determine, whereas you need to launch it.

31Mar/11Off

Building IzPack installers on the fly

One can grab ideas on how to build IzPack installers on the fly from izpack-maven-plugin.

You will of course need to depend on IzPack standalone compiler.

Basically, what do you need to do is to have some directory for staging. This is useful, when you want to run some filtering or putting some additional resources from somewhere else to the installer. You can use %TEMP% directory (File.createTempFile(...)) for that. Do not forget to wipe it afterwards!
When you have all your installer resources in some staging directory and you know the direct path to your install.xml you are ready to build a installer:

CompilerConfig compilerConfig = new CompilerConfig(installXmlPath, stagingDirPath, null, targetFilePath);
compilerConfig.executeCompiler();
30Mar/11Off

Panel for Reading Registry in IzPack 4

The panel called RegistryReaderPanel. It can be used in automated installation (silent installations). However, it can be used only once (can be easily extended). Code depends on IzPack COI tools. So COI tools classes need to be delivered together with the panel. Panel is built using Maven, so COI tools are shaded with Maven Shade Plugin. By default we are reading from HKEY_LOCAL_MACHINE registry root. You have to provide an xml file specifying what you want to read and to which variable to store the read value. Here is an example:

<registryReader>
  <registry key="SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\myApp"
      name="DisplayVersion" default="null" variable="myApp.version" />
</registryReader>

You may have several registry entries to read multiple keys. name specifies registry key. variable specifies to which variable to store the value. default specifies what should be a default value, when key was not found.

You will also need to provide COI dlls in install.xml:

<native type="3rdparty" name="COIOSHelper.dll" stage="both">
  <os family="windows" />
</native>
<native type="3rdparty" name="COIOSHelper_x64.dll" stage="both">
  <os family="windows" />
</native>

You will need to separate COI package yourself and add it to your Maven repository.

And here is the panel source:izpackExtensions-registryReader

24Mar/11Off

IzPack. Adding 64bit support.

IzPack should work everywhere. However, you have to be aware about several things if you have support for 64bit machines.

First, if you are using COI tools from IzPack (for example if you have your own custom panel that works with registry or using CheckedHelloPanel) you also have to deliver 64bit dll:

  <native type="3rdparty" name="COIOSHelper.dll" stage="both">
    <os family="windows" />
  </native>
  <native type="3rdparty" name="COIOSHelper_x64.dll" stage="both">
    <os family="windows" />
  </native>

The second thing, if you are using ShortcutPanel, you will also have to deliver 64bit dlls:

  <native type="izpack" name="ShellLink.dll">
    <os family="windows" />
  </native>
  <native type="izpack" name="ShellLink_x64.dll">
    <os family="windows" />
  </native>
17Mar/11Off

Custom IzPack Panels. Necessary Changes for Silent Installation.

Here I described how to develop and debug your own custom panel. However, in order to have it work with automated installers (aka silent installation) we need to add some changes.

You will need to add AutomationHelper class. Here is how you can do it. Assuming you have custom panel with a name MyPanel, create class MyPanelAutomationHelper in the same package. This class has to extend PanelAutomationHelper and implement PanelAutomation. And then you will have to specify how to run the panel silently.
Basically, you can just repeat all the routine from panelActivate method in MyPanel panel (or if you do not want to repeat yourself, invoke/call MyPanel smartly). But you cannot use UI stuff like emitWarning or emitError. If you need to inform user about something -- write it directly to the output. Silent installer should be silent.

Here is AutomationHelper class for MyPanel panel, which we developed previously:

package com.izforge.izpack.panels;

import java.util.List;

import com.coi.tools.os.win.MSWinConstants;
import com.izforge.izpack.adaptator.IXMLElement;
import com.izforge.izpack.installer.AutomatedInstallData;
import com.izforge.izpack.installer.InstallerException;
import com.izforge.izpack.installer.PanelAutomation;
import com.izforge.izpack.installer.PanelAutomationHelper;

public class MyPanelAutomationHelper extends PanelAutomationHelper implements PanelAutomation {

  @Override
  public void makeXMLData(AutomatedInstallData installData, IXMLElement panelRoot) {
    //
  }

  @Override
  public void runAutomated(AutomatedInstallData installData, IXMLElement panelRoot) throws InstallerException {
    System.out.println("Hello, IzPack");
  }
}
11Mar/11Off

IzPack Panels: Things You Have to Know When Developing Registry Panels

There are certain things one has to know when developing panels that interact with registry.

CheckedHelloPanel is an example of interaction with a registry. If you decide to go that way, you will need to do some additional things too besides writing the code.

First of all, you will need to define a COIOSHelper.dll in your install.xml:

<native type="3rdparty" name="COIOSHelper.dll" stage="both">
  <os family="windows"/>
</native>

The second thing is that if you take a look into CheckedHelloPanel code, you will see, that it also uses some com.coi.tools code. You will need to include that into your panel jar too.
Here is the way how we do it. First, we took this com.coi.tools and put it to our maven repository. For each our custom IzPack panel we have a separate maven module nesting some common parent routine (I have already described it in one of the previous posts. Then during package phase of our custom panel code we use Maven Shade Plugin to combine sources of com.coi.tools and our panel code.

The third thing deals with development cycle. If you develop your own custom panel to work with registry using the way , you will need to place dlls inside "izpack" project.
Create src\native folder and copy dlls from bin\native directory in IzPack installation. Then you could use them inside install.xml:

<native type="3rdparty" name="COIOSHelper.dll" stage="both">
  <os family="windows"/>
</native>

This is because com.izforge.izpack.util.Librarian in IzPack has to know where to find the dlls. Since we import only the sources to Eclipse, dlls are not imported, so we have to do that manualy.

9Mar/11Off

Silent Panels in IzPack

In your custom IzPack panel you may want to do some routine silently. In this case you would need just to skip your panel:

  @Override
  public void panelActivate() {
    ...
    parent.skipPanel();
  }
Tagged as: , Comments Off
2Mar/11Off

IzPack: Adding Custom Panels without Rebuilding Standalone Compiler

On FAQ page of izpack-maven-plugin there is a link on how to include own custom panels without rebuilding standalone compiler. I will describe our own approach.

We have a specific Maven project for IzPack extensions. For every custom panel we have a child module. Basically, each child module is just a plain Java project with required IzPack structure.

We have a special Maven parent project for all our installers. This parent defines 3 steps to build IzPack installer in pluginManagement section:

  • Copy all dependencies to specific folder defined by child installers. Then we will pick up these dumped files in install.xml file. It is used to dump our own product, third party stuff and our own custom panels, which are referenced from dependency section in pom.xml
  • Filtering step. We run filtering through all IzPack files to automatically replace version, name, path to files (fx dumped in previous step) in install.xml and all other resources. Filtered files are copied to specific staging directory. We use Maven resources plugin for that purpose.
  • The last step defines the routine to build IzPack installation

All child projects have to do is to inherit these plugins from parent.

As I said, our custom panels are ordinary Maven projects. In each installer in dependency section in pom.xml we add a reference to custom panel project. As I described above, all jars are dumped in specific folder and we just have to pick them in our install.xml:

<panel classname="MyPanel" jar="${dependencies.dir}/izpackExtensions-myPanel-${izpackExtensions.version}.jar" />

Where dependencies.dir and izpackExtensions.version are ordinary Maven variables which are substituted during filtering step.

1Mar/11Off

Reading XML File in Custom IzPack Panel

Sometimes it is needed to have some configuration file in your custom IzPack panels. It is easy to have one!

First, you have to reference your configuration file from resources section in install.xml file:

<resources>
  <res id="mySpec.xml" src="mySpec.xml" />
</resources>

Then you would need to

28Feb/11Off

Developing and debugging IzPack panels in Eclipse

Here I will describe how one can develop and debug own IzPack panels using Eclipse.

First go and download IzPack. We will use 4.3.3 vesion here.
After installation you will find source directory src\lib in installation location. Import it into Eclipse. Or create a Java project in Eclipse and copy sources afterwards. Obviously, project has some dependencies, so in Java Build Path add all external jars from IzPack installation folder lib. Now you should not have any errors. IzPack code is now browsable.

You can have a