XUL Application Packaging
Contents
Project Name
XUL Application Packaging
Project Description
Help to develop an automated packaging system for XULRunner applications.
Resources:
- Automated Packaging System
- plasticmillion, mfinkle, #mozpad, #prism
Project Leader(s)
Project Contributor(s)
- Rob Mensching - Helped understanding WiX
- Mark Finkle - Anything to do with XUL
Project Details
Introduction
Creating an application packager to allow developers of XULRunner applications to focus more on development, rather than the tedious work of having to figure out how to bundle and deploy their application. Developers shouldn't need to focus on this simple task, they should be able to quickly and easily put their new application into a packager and have those repetitive tasks done for them, so they can prepare for deployment.
XULRunner
XULRunner is a runtime environment developed by Mozilla for providing a common backend for XUL applications.XUL-based applications include Firefox, Thunderbird, Songbird Flickr Uploader, SeaMonkey, which all run off or have the ability to run from XULRunner.
- I have heard of XULRunner only once, at the Mozilla Developer Days, but I have no idea how it works, so after downloading and installing, first step is to break down how the XULRunner environment works.
- the sdk download is about 21MB~30MB depending on what platform, and once downloaded it only needs to be unzipped or untarred into an directory, I just dumped it in root, so I don't have to move around directories too much.
- Surprisingly I've learned that XUL is mixture of XML files and JavaScript, stuck into a simple directory structure.
+ /AppName | +-+ /chrome | | | +-+ /content | | | | | +- main.xul | | +- main.js | | | +- chrome.manifest | +-+ /defaults | | | +-+ /preferences | | | +- prefs.js | +-+ /extension | +- application.ini
- the application.ini file simply sets some meta information about the application, and min and max version the application will work with
- the chrome.manifest file is used to locate application resources
- the prefs.js' tells XULRunner where is XUL application file is, to open the main window
- the main.xul file is basically the physical layout of the application, which is written in XML
- the main.js file is all the logic for the application, written in JavaScript
Writing Programs in XUL
The two main files in any XULRunner application are the .xul and .js file in the content directory. the .xul file gives your application all the layout detail of the program, very similar to something like an HTML file for a web page. The .js file give your application all the logic needed for your application to be useful, similar to an external JavaScript used on an HTML page, or an CSharp file linked to an ASP web page. For XRap I am calling my JavaScript file in my XUL application using:
<script src="XRap.js" type="text/javascript"/>
To call a function in my JavaScript file from XUL is use
<command id="cmd_read" oncommand="getFile()" />
- where the control on the XUL app calls the id of the command
<button id="btn_read" label="Read File" command="cmd_read"/>
File IO in XUL
Reading Files in XUL
Writing Files in XUL
The File Picker
One of the goals of this packager is for it to be platform independent. By using the File Picker, not only does it make it easy for the end-user to select the location of their application, but nsIFilePicker will return a platform specific path to the program.
function openDirDialog() { const nsIFilePicker = Components.interfaces.nsIFilePicker; var fp = Components.classes["@mozilla.org/filepicker;1"] .createInstance(Components.interfaces.nsIFilePicker); fp.init(window,”Select Directory”,nsIFilePicker.modeGetFolder); var ret = fp.show(); if (ret == nsIFilePicker.returnOK || ret == nsIFilePicker.returnReplace) { applicationPath = fp.file.path; document.getElementById(’tb_inputPath’).value = applicationPath; } }
There are different modes which the File Picker can operate which can be found here
The Wizard
In a push to get the UI to work with the program, I looked into XUL wizards. When I think about it, there is really only two buttons to push, one to load the app directory location, and the other to package the app, it's just a matter of doing it in the right order to get an output file. After a talk with Dave Humphrey a while back, he put it into my head that I should make it a wizard, which is essentially what my program is.
Creating a wizard in XUL, is really a matter of knowing what you want the user to enter for each step, and then making a wizard page for it.
<?xml version="1.0"?> <?xml-stylesheet href="chrome://global/skin/" type="text/css"?> <wizard id="example-window" title="My First Wizard" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> <wizardpage> <description> This is my first wizard" </description> <label value="What do you want to know?"/> <menulist> <menupopup> <menuitem label="How to make a wizard"/> <menuitem label="How to make a wizard page"/> <menuitem label="All about XUL"/> </menupopup> </menulist> </wizardpage> <wizardpage description="This second wizard page"> <label value="Anything else to it?"/> </wizardpage> </wizard>
For XRap however, I wanted separate pages for each platform, depending on what the user is working on. Especially since packaging for Mac can only be done on a Mac, and cross packaging for Linux and Windows is quite buggy right now. Its the best solution to keep them separate. I used the 'navigator.platform' on the first wizard page to filter the platform, and direct the user the platform specific second wizard page. The second page will be where the app actually gets packaged. Finally the third page is just a generic Packaging completed page.
- I recently got some feedback on my blog, that I should add a button to open the location for where the package was created. I'll definitely add this for my next release!
Windows Development - WiX
Creating a Basic WiX file
WiX begins with a fairly simple XML file, which will once compiled and linked will generate an msi installer. That's if you want to create an installer for your target users just to click and install completely automatically. The WiX file is labelled with a .wxs extension and has this XML schema:
<?xml version='1.0' encoding='windows-1252' ?> <Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'> <Product Name='FooBar' Id='ADD A GUID' Language='1033' Codepage='1252' Version='1.0.0' Manufacturer='Zoo'> <Package Id='DIFFERENT GUID' Keywords='Installer' Description='Zoo 1.0' Comments='None' InstallerVersion='100' Languages='1033' SummaryCodepage='1252'/> <Media Id='1' Cabinet='Sample.cab' EmbedCab='yes' DiskPrompt="CD-ROM #1" /> <Property Id='DiskPrompt' Value="Zoo Installer [1]" /> <Directory Id='TARGETDIR' Name='SourceDir' > <Directory Id='ProgramFilesFolder' Name'PFiles'> <Directory Id='Foo' Name='Foo'> <Directory Id='INSTALLDIR' Name='FooBar' LongName='FooBarApplication'> <Component Id='MainExecutable' Guid='A DIFFERENT GUID'> <File Id='FooBar.exe' Name='FooBar.exe' LongName='FooBarApplication.exe' DiskId='1' Source=...> <Shortcut /> </File> </Component> ...-> MULTIPLE COMPONENTS CONTAINING FILES </Directory> </Directory> </Directory> <Directory Id='ProgramMenuFolder' Name='PMenu' LongName='Programs'> <Directory Id='ProgramMenuDir' Name='FooBar' LongName... /> </Directory> <Directory Id='DesktopFolder' Name='Desktop' /> </Directory> <Feature Id='Complete' Level='1'> <ComponentRef Id='MainExecutable' /> ...-> ONE COMPONENTREF FOR EACH COMPONENT FROM ABOVE </Feature> <Icon Id='FooBar.exe' SourceFile='FooBarApp.exe' /> </Product> </Wix>
This a very rough layout of the file, for a complete tutorial visit: WiX Tutorial
WiX Tools
The main tools that most users will use:
- candle.exe
- is the Wix Compiler
- which takes the .wxs creates a .wixobj
- light.exe
- is the Wix Linker
- takes the .wixobj and creates a .msi
- dark.exe
- is a Wix decompiler
- taking the .msi back to a wxs source file
There is a great diagram of all of the Wix tools here: WiX Toolset
Project Plan
The plan for XRap is to be broken down into three major releases, the first being Version 0.3 (which has already been completed) is the Windows packager, while the next two will be the Linux and Mac packagers.
Version 0.4
This will be an update to the 0.3 release, where WiX has an advanced installation section, which XRap will need to access. The Advanced installation will allow developers to customize their installer, by adding logos, and allow the user to select a custom install.
Version 0.5
This release will be mainly a quick and dirty package of a XUL application, and an installation on to a Linux box. The main goal being to learn installation directories, and any advanced setup techniques which an application may need to be set up for. For now I will make this a separate application, apart from my 0.3 release.
Version 0.6
Merge my Version 0.5 and 0.3 into one application, update the UI, and include any advanced setup options needed for installation onto a Linux box. I will also add a logging feature for packaging, so that the developer will have a log of all files and directories being packaged, as well as intended installation paths, and GUID’s assigned.
Version 0.7
Similar to my 0.5, I will create a separate application to create a packager for installing XUL applications on a Mac box. Advanced settings, installation paths, and other options will need to be sorted out for the Mac release.
Version 0.8
Merge my Version 0.7 with 0.6 into one application, update the UI, and include any advanced setup options for Mac users. Begin documentation of how this application is supposed to work. Work on bugs
Version 0.9
Complete Documentation, and continue fixing bugs. The UI will most likely be updated and tweaked.
Version 1.0
All bugs should be fixed, and for the most part just cosmetic updates to the UI will be done.
Project News
- Offically started project on September 18, 2008
- September 20, 2008
- Downloaded XULRunner SDK
- Followed tutorial and started to build small XULRunner applications, learning about the structure of XULRunner apps
- Downloaded some applications which others have created to get an idea of the structure others are creating their app
- Found out that the most of the code is being archived into a .jar file
- Problem: Don't know if this will create a problem when installing
- Downloaded XULRunner SDK
- September 29, 2008
- Talked with Mark Finkle and Dave Humphrey on IRC about various Application Packagers for Windows
- Talked about milestone goals for my project, and set them:
- Version 0.1: Stable Windows release of Packager
- Version 0.2: Stable Linux release
- Version 0.3: Stable Mac OS release
- October 2, 2008
- Browsed through the list of Application Packagers which were recommended by Mark and Dave
- Decided to use WiX as my Packager of choice, mainly because of their use of XML
- October 6, 2008
- Began going through the manual for WiX
- Followed the tutorial on packaging their sample application
- Success! I made an .msi file and installed it on my computer on the first try! It installs into the 'Program Files' directory and adds an item to the Start menu
- Solved: Files in the .jar file don't need to be taken out of the archive for the program to work, which won't create a problem when installing
- October 8, 2008
- Decided to use C# to generate the XML file and passes it to WiX for packaging
- Began coding a command-line based program, which will take one arguments as the root directory of a XULRunner application, and generate an XML file for WiX
- Using the sample WiX application, I was able to generate the .wxs XML file, and using WiX manually generate a working .msi
- Created a recursive algorithm to get all files and sub-directories of a XULRunner application
- Problem: I have no problem getting the all the files and sub-directories, the problem is adding them to the XML file in the correct structure which they came from
- October 9, 2008
- Working on structure problem, can only get the files and directories to be added one level deep in the XML file
- October 16, 2008
- Working Solution: Using the Stack I am able to get 2 levels deep, it will work for basic XULRunner applications
- October 20, 2008
- Figured out how to go through the directories recursivly
- October 24, 2008
- XRap version 0.1 Officially Released
- November 4, 2008
- It was suggested to make this an entirely XULRunner based program, it makes sense, so today I made a simple XUL app, with some buttons, label and textbox.
- I figured out how the XUL file and the JavaScript file are linked, which is by using <command> in the XUL file to call a function in the JavaScript file.
- Hooked up the buttons to output text from a textbox to a label
- November 9, 2008
- Looking into doing File I/O, Mark Finkle directed me to a page on MDC, and I found some stuff on XULPlanet
- Managed to read a file, as well as get the Directory name where the file was located
- Learned about .leafName from some guys on IRC, which gets the name of the directory or file, without the need to parse it (I had to parse through the path to the directory/file using string manipulation)
- November 14, 2008
- Started reading about creating an XML document in XUL, there is very little documentation on it
- After a long conversation in the #Xulrunner channel, I was directed to use the JavaScript implementation of XML
- November 16, 2008
- XML turned out to be quite easy in JavaScript, in creating the nodes from the XML document
- I ended having to use the nsIDOMSerializer interface and the xmlserializer component to make the XML file
- I am getting a better handle on how JavaScript works, and figured that XUL is used for creating controls for an app, while the JavaScript gives those controls its functionality
- November 22, 2008
- I can't seem to findout how to run a execute a program from JavaScript, it seems to be practically forbidden
- Found a simple JavaScript GUID generator, I don't feel like its the best solution though, I'm looking for a GUID generator function in JavaScript
- November 25, 2008
- Mark Finkle commented on my blog about the nsIUUIDGenerator interface, for generating the GUID for the WiX file
- December 2, 2008
- The guys in #Xulrunner told me to look into nsIProcess for running external applications
- Created a batch file to executing the candle.exe and light.exe WiX programs, to compile and link the wix files
- December 4, 2008
- Found the.run() function of nsIProcess, which can execute candle.exe and light.exe from the command line, without the need of creating a batch file.
- Fixing compile errors I get when the WiX programs candle.exe and light.exe run against the .wxs file XRap creates
- December 6, 2008
- Adding validation to the code, to check for files WiX files created before
- Adding validation to check for the XULRunner runtime, and if its directory is in the applications directory
- December 10, 2008
- Removing unnecessary code, and fixing the UI
- December 13, 2008
- XRap v0.3 for Windows is Released
- January 14, 2009
- Studied the WiX Tutorial and Documentation on how to implement the UI features
- January 15, 2009
- Built some sample applications to see how the various UI's are implemented, and how the custom Bitmaps and Licenses are applied to the installers
- Started applying the changes to the XRap UI
- January 19, 2009
- Edited the generators of the .wxs and .wixobj WiX files, to accommodate the new UI
- So far the only problem is that the customizable installer will need to keep track of certain files which can be optionally installed
- February 11, 2009
- Completed Linux Packaging
- Using Autotools, managed to get Makefiles created, and tarballed the application directory
- End user will now be able to use 'make install' to install application to /usr/bin directory
- February 15, 2009
- Had to change how I used some of the autotools, need to execute them using scripts, because they are not reading the correct directory
- Completed the scripts, but the tools still don't seem to work
- February 16, 2009
- Implemented the nsIFilePicker dialog to get the application's directory path from the user
- February 17, 2009
- Started to merge my Windows and Linux releases
- Kept the Javascript in their two different files
- Refactored the Windows javascript to handle files and folders in a cross-platform manner (by using the append() method from the nsIFile interface)
- February 22, 2009
- Continued refactoring the Windows code, trying to get it to work on Linux
- Attempting to have some common variables in the javascript, so that the two files can work with it.
Releases
Version |
|
0.1 |
|
Command: XULRunnerApplicationPackager.exe [Path to XulRunner Root Folder] | |
0.3 | XRap v0.3 Installer |
0.3 | XRap v0.3 Source |
0.4 | XRap v0.4 Installer |
0.4 Source | XRap v0.4 Source |
0.5 | XRap v0.5 Installer and Source |
0.6 | XRap v0.6 Source |
To Do
-
Learn how XULRunner works -
Build a XULRunner Application -
Find other XULRunner Applications -
Learn about Packagers and what they do -
Choose a Packager -
Learn about the Packager selected- WiX is the packager I am going to be using
-
Package a small application- WiX tutorial offered me a sample application to follow with
-
Create or find a XULRunner app, package it, and install it -
Create a program to Package a XULRunner appOnly works with simple apps-
Automatically generate WiX XML schema of Directory structure This is the problem area -
Generate GUID, and pass it to WiX Code (Used Guid structure in .NET Framework) -
Get argument from command-line of the location of the XULRunner app
-
-
Learn how to create a XUL app - Learn JavaScript
-
How to call JavaScript from XUL app -
Using the Mozilla/XUL Interfaces
-
- XUL
-
File IO using Interfaces-
Reading files -
Writing files
-
-
XML using Interfaces -
Executing System Commands
-
-
Clean up code -
Do some validation
- 0.8
- Merge completed Mac packaging into XRap
- Create a log file, storing:
- all output from status box
- guid's created
- errors
- Mac
- get correct package name from application.ini
- 0.9
- Add icon support in Wix script
- Windows
- zip files for Mac and Linux distro and add script to run '--install-app' for each
- Linux
- zip files for Mac distro and add script to run '--install-app'
- Mac
- zip file for Linux distro and add script to run '--install-app'