Portable Perl Applications on Windows

Deploying a Perl based application to Windows users raises the question of whether and how to bundle the required Perl runtime and libraries.

If you don't want to force the user to install a Perl distribution, the usual answer is: "Use a Perl packer".

"pp", probably the most common packer among them, creates a single exe. I think the design choice for a "one-file solution" was not based on objective requirements analysis. I will provide a simpler solution below.

Requirements

That's my idea of important requirements:

  • The application must be located in a directory tree freely specified by the user. Rationale: The user can decide whether or not to have it write-protected, and the installation is transparent to the user.
  • The application shall be (optionally) reachable via the search path.
  • The application should be "portable": Unpack it somewhere and it runs without any configuration or patching.
  • Calling the application shall be simple, appname.exe instead of "perl.exe appname.pl"

Apart from that, I prefer solutions to be as simple as possible.

Simply bundle everything with a smart launcher .exe

From a system perspective, the simplest method is to bundle all required files in one directory tree and provide an appname.exe calling the Perl interpreter.

The perl.exe of current Perl distributions does hardly more than "RunPerl(argc, argv, env);" But it's a bit awkward to call "installpath\perl.exe installpath\appname.pl".

A smart(er) launcher just needs to:

  • Get its own full path with GetModuleFileName();
  • Replace ".exe" with ".pl"
  • And add this path to the RunPerl() parameters

Name it "appname.exe" and place it next to appname.pl (and the Perl DLLs). Then you can call it from anywhere, like any other "native" Windows application.

To avoid collisions of additional files (e.g. libraries), use a configuration where the Perl script and DLL are located in a specific subdirectory. The "installation directory" will then only contain appname.exe and a directory "appname_files", holding all the other required files.

Download

Get a demo and C code here: ppl.zip Use at your own risk!

The archive contains also an unpar.cmd for automatic unpacking of executables generated by PAR/pp.

A full ExifTool installer using Strawberry Perl is available here: ExifTool-for-Windows

Perl Packers

Free, open source:

Free, closed source:

Commercial:

Potential problems using the PAR Packer pp

The PAR Packager "pp" authors write 'You may think of pp as "perlcc that works without hassle". :-)'.

I have to admit that the prospect of a monolithic exe, created by a simple command, is tempting.

But at least for Windows, pp doesn't seem that reliable to me. Users of popular tools using pp (Biber, ExifTool and dependent programs) are experiencing problems regularly.

The usual reflex is to blame "the bad Windows" and Defender. Users are advised to run the application as administrator and to disable Defender. That's easily said but the wrong approach.

As far as I see, pp itself is the cause of many problems, here are some reasons:

Using the temp directory for executables

pp does not create a real monolithic exe, but rather a self-extracting archive, unpacking executables and scripts to the Windows temp directory. This design choice has some bad consequences:

  • Unwanted change of extracted files, e.g. by maintenance tools (cleaners) or even malware.
  • Running executables in is the same method that Emotet uses and considered suspicious by many AV products and even might be blocked by system policies.
  • It's cluttering temp with old versions since there is no "uninstaller", and most users are not aware of the hidden unpacking.

Users are often advised to set PAR_GLOBAL_TEMP, but this causes other problems and is "discouraged" according to the maintainer.

There were patches tinkering with symptoms, e.g. "biber" files vanished from the cache directory, but not solving the root problem: Executables shall not reside in the "temp" folder!

Setting an incompatible environment

To put it politely: pp sets Perl variables in an unexpected manner. For example, $0 contains the name of the exe instead of the script name which will break existing path calculations in your application. $^X is set to "perl.exe" (but there is no perl.exe) and @INC has garbage entries.

The boot process is way too complicated

The pp boot process runs a first Perl interpreter by passing a 20KB "one liner" (!) and then spawns a second process, using several environment variables and mangled command line arguments.

As long as you don't use the advanced functions of the PAR archives, it's all useless.

Embedding non-portable Perl configuration

pp copies "non-portable" configuration data from the Perl installation to the resulting archive, e.g. "config.pm" usually contains many absolute paths and other critical settings. This is no pp-specific problem but it's easy to overlook since pp promises automatic resolution.

Incomplete dependency resolving

The PAR Packer doesn't (can't) resolve all dependencies automatically. Depending on the complexity of the app, it may take many bug reports from users until every needed module or other file is added manually. That's also a problem of other solutions.

After all: pp is not exactly the most beautiful code ever written. Don't look at it if you are faint-hearted. Roderich Schupp once wrote: "the code base is very brittle and prone to breaking stuff at a distance".