Perl Dev Kit

Making expiring ("time bombed") executables with PerlApp.

Question: 

Can I put a time limit on my executeable which I create with PerlApp?

Answer: 

Yes. This sample program will run normally when you invoke it as `perl expire.pl`, but will refuse to run after the expiration date when it has been compiled with PerlApp.

You could hard-code the expiration data in your program, or you can supply it when you build the executable and retrieve it inside your application from a bound file:

BEGIN {
    return unless defined $PerlApp::VERSION;
    my $expire = PerlApp::get_bound_file("expire") or return;
    my($y,$m,$d) = (localtime)[5,4,3];
    my $today = sprintf("%04d-%02d-%02d", $y+1900,$m+1,$d);
    return if $today le $expire;
    print "expired\n";
    exit;
}
print "ok\n";

For example:

c:\tmp> date /t
Wed 02/14/2007

c:\tmp> perlapp -f --nologo --bind expire[data=2007-02-13] expire.pl

c:\tmp> expire
expired

c:\tmp> perlapp -f --nologo --bind expire[data=2007-02-14] expire.pl

c:\tmp> expire
ok

PerlSvc: Current Working Directory for Windows Services.

Question: 

PerlSvc: What is the current working directory of a Windows Service?

Answer: 

The Windows Service control Manager uses C:\WINNT as the current working directory, not the directory where the PerlSvc executable is stored.

PerlMSI Starter

Question: 

I installed the Perl Dev Kit but don't see an icon for the PerlMSI utility. Am I missing something?

Answer: 

PerlMSI does nt have a gui interface but instead a script ( 'msiwiz.pl' ) and MSI::Installer module. Our best suggestion for getting started with PerlMSI would be to read the documentation:

msiwiz - Wizard Interface

...and take a look at the PerlMSI sample in the samples directory.

As well you will need to install the Microsoft Installer technology SDK.

What is the ECCN for the PDK?

Question: 

What is the Export Classification Control Number for the Perl Developers Kit?

Answer: 

The Export Control Classification Number for the PDK is EAR99 (self-classified). For a brief description of EAR99 and information on the difference between EAR99 and NLR (No License Required), see:

http://www.census.gov/foreign-trade/faq/reg/reg0031.html

Programs using Perl source filters can't be wrapped with PerlApp

Question: 

I wrote a script that uses the Switch Perl module. It works great unwrapped, but when I wrap it with PerlApp it doesn't work.

Answer: 

This happens because the Switch module is implemented as a Perl source filter. Currently, code that uses source filters cannot be processed by PerlApp. There is no easy work-around for this that I am aware of -- the only option at this point seems to be to convert the code using Switch to use if...elsif...else clauses or one of the other alternatives from the perlsyn manual page.

Using PerlApp with Unicode source files including a BOM

Question: 

My Perl program works great, until I compile it with PerlApp. When I run the executable, I get the error message "Unrecognized character \xEF at foo.pl line 1."

Answer: 

Fortunately, this one has an easy, though easy-to-miss solution.

The file is saved in Unicode, and there is a Byte-Order Mark (BOM) present. A BOM helps a text editor figure out what byte order the file is saved in, but it can cause problems with PerlApp and other tools.

The solution is to save the file (or a copy of the file) without a BOM, and use that copy of the file when running PerlApp.

Using Komodo you can turn off BOMs for the current file by going to Edit | Current File Settings and deselecting "Use signature (BOM)". Other editors will do it different ways, but it's almost always possible -- check the manual or help system for your editor.

PerlApp with Perl 5.8 generates huge executables

Question: 

When I use PerlApp with Perl 5.8 the resulting executable is several times larger than when I used Perl 5.6. How do I make it smaller?

Answer: 

More than a few people are surprised when they upgrade to PDK 6.0.x and ActivePerl 5.8. In addition to being more solid than ActivePerl 5.6 with PDK 5, the freestanding executables are sometimes three or four times larger.

There is one word that is responsible for much of this apparent bloat: Unicode.

When PerlApp puts together an executable in freestanding mode, it has to be sure to include all required modules and their contingent bits and pieces. Because PerlApp can't tell if a conditionally required module will be needed, it includes it to be on the safe side. Often, this is how the Unicode modules (which aren't all that big) and the translation tables (which are that big) get involved.

The easiest way to cure this problem is to trim out the Unicode modules and related files using the PerlApp graphical user interface, or --trim arguments on the command line. Whichever way you choose, you should be aware that some modules generate and use Unicode internally. If your application begins to fail after removing the Unicode modules and/or translation tables, you will need to play with it a bit to figure out which are needed and which aren't for your given application.

The best way to get the initial settings correct is to use the PerlApp graphical interface. There you can see which modules and extra files will be included, and have the opportunity to trim them out. When you have everything set up correctly, the Output tab of the graphical interface will show you the command line you need to use to reproduce the build with those settings.

This should bring the size down substantially. If it does the trick for you, let me know and I will give some rough numbers that I hear from people as examples in a future version of this entry.

Including POD in PerlApp executables

Question: 

How can I include POD in scripts and modules compiled by PerlApp?

Answer: 

When PerlApp compiles your code, it strips out all pod from script or module files. If you need to use pod2text, you can work around this by:

  • including the pod data in a separate .pod file
  • including this .pod file in your build using the --bind option.

Here's how you create perl scripts that will work both as a script and an executable (working with bound files):

  # this is the file we want to access in our code
  my $file = "/path/to/this.file";

  # test if we are running as a script or executable
  $file = PerlApp::extract_bound_file($file) if defined $PerlApp::VERSION;

You would then build the PerlApp executable using the --bind option:

  perlapp myscript.pl --bind this.file[file=/path/to/this.file]

See also:

Perl Docs

Restoring the native Perl debugger on 32 bit systems

Question: 

How do I switch back to using the native Perl command line debugger?

Answer: 

When the Perl Dev Kit is installed, the PDK's Graphical Debugger becomes the default debugger, replacing the console debugger included with your Perl distribution.

To disable the Graphical Debugger included with the Perl Dev Kit and use the console debugger instead, perform the following steps:

  1. Ensure that the Graphical Debugger is set to remote mode.
    • On the command line, enter pdkdebug --query to view the current mode.
    • If necessary, enter pdkdebug --remote to set the debug listener to local mode.
  2. Set the debugger to the console debugger included with Perl 5.x. On the command line, enter:
        set PERLDB_OPTS=

To disable the Graphical Debugger permanently, remove the PERL5DB key from HKEY_LOCAL_MACHINE\SOFTWARE\Perl and remove the PERLDB_OPTS system environment variable.

Distributing PerlRt.dll with your PerlNet component

Question: 

What do I need to deploy with my PerlNET component?

Answer: 

PerlNET components built with the --freestanding option are not completely freestanding; you also need to deploy perl56.dll (or perl58.dll), perlnh.dll and perlrt.dll.

PerlNH60.dll can be found in the PDK bin directory (usually C:\Perl\bin directory or C:\Program Files\ActiveState Perl Dev Kit 6.0\bin.

PerlRT60.dll is more difficult to find because it is moved to the .NET Global Assembly Cache during installation of the PDK. Copy it out of the GAC by opening a DOS prompt and changing to the PerlRT60 directory:

  c:\> cd c:\WINDOWS\assembly\GAC\PerlRT60\

This directory should contain only one subfolder. Use 'dir' to find the name. For example:

  6.0.2.6772__cea8284aa6739163

Copy the .dll from this folder like this:

  C:\WINDOWS\assembly\GAC\PerlRT>copy 6.0.2.6772__cea8284aa6739163\perlrt60.dll c:\tmp

Note: On Windows 2000 and NT systems, the WINDOWS directory will be called WINNT. With previous versions of the PDK, the DLL filenames do not contain a version numbers (i.e. PerlRT.dll and PerlNH.dll)