Win32::Packer - Pack your Perl applications for Windows


  use Win32::Packer;

  my %args = ( app_name => 'Hot-Dog Vendor Revengeinator',,
               app_vendor => "Doofenshmirtz's Quality Bratwurst",
               app_version => '0.1',
               app_id => 'YOUR_APP-GUID-GOES-HERE-dc9c9d79a96c,
               license => 'files/license.rtf',
               icon => 'pixmaps/hot-dog-vendor-revengeinator.ico',
               scripts => [ { path => 'bin/',
                              shortcut => 'Hot-Dog Vendor Revengeinator',
                              shortcut_description => 'Sends off blasts to hot dog vendors '.
                                                      'encasing the hot dogs in ice',
                              handles => { extension => '.hdg' } },
                            { path => 'bin/' },
                            { path => 'bin/',
                              firewall_allow => 'localhost' } ],
               app_subsystem => 'windows',
               extra_inc => [qw(lib)],
               extra_module => [qw(HotDog::Vendor::Finder::Impl::Windows
               extra_exe => [ { path => 'c:\\program files\\blaster\\blaster.exe',
                                subdir => 'blaster' } ],
               extra_dir => [ { path => 'pixmaps',
                                subdir => 'pixmaps' } ],
               search_path => 'dll',
               output_dir => 'output' );

  my $packer = Win32::Packer->new(%args);

  $packer->make_installer(type => 'msi');
  $packer->make_installer(type => 'zip', compression_level => 'best');


  *                            WARNING!!!                               *
  *                                                                     *
  * This is an early experimental release of Win32::Packer.             *
  *                                                                     *
  * The API is not stable yet and I would change it in order to improve *
  * the module usability, implement new features, etc. at will.         *
  *                                                                     *
  * Though, working installers would keep working!                      *
  *                                                                     *

This module allows one to pack Perl applications for distribution to Windows users.

It tries to be simple to use and feature rich.

It is also opinionated and its customizability is rather limited.

The module provides several backends allowing you to generate the installers in several formats, being the main ones the msi backend which generates standart MSI files and the zip installer that generates ZIP archives that can be unzipped in any location in the target computer (aka, portable distributions).

The usage of the module as show in the synopsis is quite simple: call the constructor passing a data structure defining your application and then for every installer type you want to create, call the make_installer method.


The Path data structure

Looking for a better name!

Several entities (e.g. scripts, executables, directories) are declared using this structure consisting of a hash containing a mandatory path argument and several optional properties. Example:

     scripts => [ { path => '/path/to/',
                    subsystem => 'windows' }, ... ];

When the only property is the path, a single scalar containing it can be used instead of the hash. Example:

     extra_inc => [ './lib', '/usr/local/my-perl-lib' ]

The available properties are as follows:

path => $path

Location of the resource being defined

subdir => $target_subdir

The target destination directory.

The generated installer will create this subdirectory inside the target directory and place the file there.

It can have several levels (e.g. subdir = 'foo/bar/doz'>).

Note that having dedicated subdirectories for every extra executable is a good way to avoid having conflicting libraries. For instance, having two executables depending on different versions of the same library.

icon => $icon_path

Sets the entity icon which would be displayed by Windows in the program windows, associated files, etc.

handles => \@handles_array

See the Handles data structure bellow.

firewall_allow => $source

Creates a firewall rule exception allowing the executable to provide Internet services. $sources can be one of localhost, localnet or all.

If your executable binds to any public network interface, recent versions of Windows would request the user to explicitly allow it unless you use this property to set an exception.

search_path => \@paths

List of extra directories to use when looking for DLL dependencies. Example:

  search_path => ['c:\\strawberry perl\\win-builds\\bin'];
basename => $basename

In several cases, the packer needs to generate files with the same name but a different extension. This property allows you to override the basename.

subsystem => $subsystem

Select the subsystem for the generated executable. Valid values are console and windows.

See the Subsystems chapter below.

cygwin => 1

For an executable, this flag indicates it is a Cygwin binary requiring Cygwin libraries. Also, the module will look for the executable inside Cygwin bin directory.

The Handles data structure

This structure allows you to declare the set of file types and URI schemes that the executable is able to handle.

The supported properties are:

scheme => $uri_scheme

Associated the executable with URLs using the given scheme. For instance, if scheme is set to 'hot-dog', once the application is installed, will call the executable when the user clicks on an url such as hot-dog:// and pass it as an argument.

extension => $ext

Associates files with the given extension to the executable.

content_type => $content_type

Associates files with the given content type to the executable.

Note that currently, only the msi backend supports associating applications.


$packer = Win32::Packer->new(%opts)

Builds a new Win32::Packer object.

The accepted arguments are as follows:

app_name => $app_name

Name of the application. Used in several places, for instance, to derive installer names and directories.

app_vendor => $vendor

The name of the vendor. Used only in the installer metadata.

app_version => $version

The current application version. Windows requires it to be two or three numbers separated by dots (e.g. 4.5 or 4.5.1).

app_id => $guid

Your application GUID. You should always use the same identifier along different versions of your application if you want upgrades to work.

license => $license_rtf

Path to a file containing the license for your app in RTF format.

scripts => \@scripts

Declares the set of scripts to pack in the installer as an array of Path data structures.

extra_inc => \@paths

List of extra directories for searching Perl modules.

extra_module => \@modules

Win32::Packer analyzes and finds dependencies for the scripts automatically using Module::ScanDeps, unfortunatelly, this module is not always able to find all the dependencies.

This option can be used to instruct the module to pack any module not automatically detected as a dependency.

extra_exe => \@exes

List of extra executables to be included on the installer.

DLL dependencies are detected and packed too.

extra_dir => \@dirs

The given directories and their contents will be included on the installer.

cygwin => $path

In case your application has any Cygwin dependency (programs or libraries), this option tells the module where to look for Cygwin.

By default the module looks for Cygwin using several heuristics.

work_dir => $path

Working dir for place temporary files.

output_dir => $path

Output directory. The generated installers will be placed there.



Windows executable subsystem

Windows has (mainly) two kind of executables: windows and console.

The more visible difference is that console applications would open a console windows when invoked without one but there are other subtle differences that may affect your programs and things that work right when you run your script using the perl executable from the command line, would fail when packed as a windows subsystem executable.

Don't blame the packer, it is Windows (or Perl on Windows) which works that way!


Mention other useful documentation such as the documentation of related modules or operating system documentation (such as man pages in UNIX), or any relevant external documentation such as RFCs or standards.

If you have a mailing list set up for your module, mention it here.

If you have a web site set up for your module, mention it here.


Salvador Fandiño, <salva@>


Copyright (C) 2017 by Salvador Fandiño

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.24.1 or, at your option, any later version of Perl 5 you may have available.

1 POD Error

The following errors were encountered while parsing the POD:

Around line 1063:

Non-ASCII character seen before =encoding in 'Fandiño,'. Assuming UTF-8