Some examples of such applications already exist in the form of Java JAR files with the application, as well as the installer runtime, bundled inside. This was the same route I took when I was developing the project in college, but quickly discovered that that was a somewhat less that efficient was of handling it.
The first time I wrote this document was over 2 years ago, and as time has gone on and the idea matured, surprisingly little has changed in it. All that has been edited are some implementation ideas, which have been kept back for another entry.
Much (to all) of what is here is already available in existing solutions, and I realise that other packages offer more. The overall difference is that it is designed to work not only on a single operating system, but on many.
I hope that at least some of you might take the time to comment on the ideas here, and perhaps offer additions or suggestions to the list.
The Cross Platform Installer
The Problem
The problem of modern cross-platform software installations affects both software developers and end-users of that software alike.
The impact of which is users of multi-format software are forced to download/purchase multiple copies of software installation files, each one designed for a different root system type (e.g. Windows, Linux, MacOS). Developers are forced to distribute multiple copies of files, versions of which for less popular formats can often be less than intuitive,
The Solution
A successful solution would utilize the ease of a Windows software installation and deliver a single, identical package capable of mimicking this standard across a variety of platforms, easing the installation process and, ultimately, benefiting the end-user. The developer would have a tool that would be capable of creating a single customizable package that could install their software on this variety of platforms, allowing them to apply specific instruction sets to the installation depending on the platform in question.
Feature List
-Familiar, intuitive interface Both the Install Creator and the Installer should have an intuitive, powerful interface. In particular, both should be built upon existing practises of desktop environments, allowing for a degree of familiarity to be apparent from the first use of the application.
-Powerful Command Line Interface The installer should also be able to cater for people who do not use a graphical environment. In this case, a set of equivalent CLI commands should be in place to allow for a similar installation experience. The CLI should follow accepted conventions for command line installations.
-Single file deployment All files regarding the installation are compacted into a single, self-extracting file. This method cuts on the overall size of the installer. Except the case of Network Stub Installation.
-Network Stub Installation Create small, easily downloaded packages that connect to a central resource holding the necessary files, and download and install via the network. Also allows repair functions to be carried out using the most up-to-date versions of files.
-Platform independence Multi-format installers will be capable of installing applications regardless of the platform, maintaining the same overall layout and ease of use.
-Platform biasing The developer is capable of creating an installation routine that will only run on a specified platform (e.g. either Windows or Linux, but not both.). This allows the developer to use the same tool for platform specific installations as platform independent installations.
-System configuration The installer should be capable of making changes or adding entries to system files necessary for the use of the application. These include Windows registry settings and changes to root system files.
-Permissions options Installations can be set to be blocked unless the current user has administration (Windows) or root (Linux) access on the machine.
-Full installation logging An option will exist for an installation to create a text document outlining all changes made to the users system.
-Installation Repair Allow an installation file to analyse individual files and values, and repair any files that do not match those in the installation file. This would allow for easy recovery in the event of installation corruption.
-Automatic uninstaller Separate application created by the installation process capable of rolling back all changes and removing all files created by the system.
Brainfart of the Hour: I wonder why all installers have traditionally been offered in wizard format, even when all you will be offered to change is the path of the installation? Only in corporate/enterprise deployment models is this pattern broken.
Execution Problems
MacOS has a cool little paradigm where the application is a folder, not a single binary file, and contains some metadata that can help the OS choose the right binary to run. This is a really cool concept, but it only ports across versions of MacOS, and even then it is fairly limited in its implementation. There is absolutely no similar corresponding paradigm in Windows or the *nixes as far as I know.
A single package file has to be executable across all platforms with a single click from the user, and requiring no interaction on the user's part to choose the correct platform. This means that you need a way to bootstrap the installer on any platform that you are targetting, and that is a nontrivial problem to solve. Admittedly I haven't spend much time trying to find clever solutions, but the concepts I've got off the top of my head are unwiedly, unstable, and not portable to new hardware/OS versions. Ideally we need cooperation between all OSes in running a single bootstrap format (in a perfect world, this would be based on a metadata scheme ala MacOS) but that will never happen because OS vendors see each other as competitors, and interoperability is not exactly Priority Number One.
Sure, a third-party vendor could come along and build a bootstrapping technology very, very easily. In fact, it's a trivial problem; wouldn't take more than a few hours to get right and in a marketable state (think a brain-dead and self-executing version of ZIP files, with a bootstrapping aid running on each target computer). Unfortunately, this requires users to have the bootstrap aid technology, and introduces a chicken-egg market penetration problem that is very, very nontrivial.
Package Volume
A single-package installer must, by definition, contain all the assets from every supported platform. In some trivial cases you can get away with some highly portable data and this space is not a big concern. However, in most non-trivial applications, you will need a lot of platform-specific stuff, both code and data. Even heavy-handed hacks like writing a pcode compiler for binary portability (like Excel did) will help, but they have a huge cost. Basically, you have to spend a ton of effort up-front during development to achieve this, and it may or may not pan out. Even in the case of using a platform-independent data representation and a middle tier to convert to each platform on-the-fly, you have a technically complex layer that is prone to failure, and it costs development time.
For fat-media products, this isn't too big of a deal (indeed, for fat-media like CDs, you can very easily do per-platform installers and fake it to look like a single package). But the real use for single-package installers is thin-media redistribution, be it on USB flash drives, over the Web, or by carrier pigeon. In all of these cases, wasted media space is a bad thing. So you have to take the hit on the development effort, which (and I know from experience) might end up costing a lot more than it sounds like on the surface.
The network stub method is really the best answer to this; IMHO, that's the only way thin-media installs should be done anyways. However, it may not always be an option, and eventually someone will complain that they can't put the entire thing on a CD and reinstall it when they're in B.F.E. and the wireless connection drops out. Being able to rely on a fat pipe to deliver the installation data would really be extremely handy, but that's a luxury we don't have in the real world - yet.
Differing OS paradigms
You touched on this in three major points: familiar interface, CLI support, and uninstallations. This is a serious and difficult problem. Interface design parameters are quite different between OSes (the infamous OK/Cancel problem between Windows and MacOS) if there are even any genuine guidelines at all (*nix). What makes sense in one OS may be completely out of place in another. This means you need a per-platform UI fork so that it feels native to each platform. You cannot ignore this - Java tried to ignore it, and Java UIs have become universally reviled and hated by developers and users alike.
CLI support will have to be implemented in many different ways on each platform. If you want older Windows support, you need a slightly different bag of tricks than just NT-based Windows support. MacOS and the *nixes are again different (although the MacOS CLI, being stolen from BSD, is actually pretty easy to get interoperating with *nix code). This is primarily a technical matter, but the bottom line is that it requires additional code branches per target platform. This means more duplicated logic across platforms, where things are done very similarly, but not similarly enough that they can be translated into pure abstractions and only implemented once.
Finally, things as major as uninstallers can come back to haunt you in a big way. The Mac platform does not have an uninstall concept. There is no centralized location to uninstall programs. The majority of Mac software is set up so you just drag it to the Trash Can and it's gone. In fact, that's the behavior that Apple mandates in their usability guidelines. Personally, I find this to be a completely idiotic decision on Apple's part, but that's how it is, and it's a very painful fact of multi-platform life that Mac users don't have anywhere near the same grasp on the "uninstall" concept as Windows users. This kind of thing has to be taken into account, and it can have massive effects on your system architecture. If, as in my case, your architecture requires an uninstall due to low-level system interactions, it can put a lot of pressure on your user-experience design to make sure that the process makes sense and is accessible to all of your users.
At this point in history, platforms simply aren't interchangeable. Frankly, I hope it stays that way; as soon as platform differentiation goes away, we've lost something useful. If platforms cease to be differentiated meaningfully, then the platforms are no longer optimal, because at least one of them is doing more than it has to (exhibit A: cell phone OSes getting 3D graphics APIs). Since, inherently, different platforms will always be different in fundamental and potentially highly application-affecting ways, 100% write-once-run-anywhere is a pipe dream. Even more realistic concepts like single-package deployment are, in many cases, a lot more trouble than they are worth.
I'm working on disentangling myself from a multi-platform product. It has a Windows version, a Mac version, and a Linux edition that is used only in embedded scenarios internally. The product shares a fair bit of its platform-independent technology via a client-server architecture, and the rest is 100% per-platform. Each has a separate deployment path. I remain confident that it was the right thing to do, because it let the development team (read: me) focus on getting the implementation right on each platform, and not on trying to get a reusable, global, portable solution that I'd have to hack back apart and make platform-dependent at some point anyways.
And we've never had a single user who couldn't tell if they needed to download the Windows installer or the Mac installer.
So, again, call me cynical... but IMHO single-package deployment is little more than a mildly interesting academic exercise [smile]