Thursday, June 7, 2012

How to make a wperl.exe executable in windows from scratch

GUI scripts
version 2.1

The standard perl.exe is a console based application, this is the right
thing usually, but sometimes it might be tedious.

Imagine you have a Tk or Win32::GUI based script, you start it by a
doubleclick on an icon and an ugly empty useless console appears and
stays on screen until you close the script. Not a nice thing huh?

There are several solutions.

Hiding the console
You may hide the console as soon as the script starts.

use Win32::GUI; BEGIN

There are three problems with this solution.

The first is that the console flashes on screen when you start the
program. Even if you use BEGIN{} to hide it as soon as possible.

Second, if you run such a script from a console, it will hide the
console instead of detaching itself and leaving the console visible and
ready to take other commands.

Now let's think about what to do when the script ends. If it keeps the
console hidden and it was started by a doubleclick on an icon everything
is cool, but if it was started from a command prompt, the prompt is
still running, but it's invisible. This way, you'd run out of memory.

If you on the other hand show the console, it may flash on screen.

For some time I advertised a way to prepare a perl.exe that doesn't
create a console. This is no longer needed if you use ActivePerl. The
distribution contains wperl.exe which is just that. If you compiled Perl
yourself you may need to create such an executable yourself. It's easier
than it may seem:

All you have to do is to copy your perl.exe to wperl.exe and run this :

c:\> EDITBIN.EXE /subsystem:windows wperl.exe

I'm using extension .gpl for the scripts that are to be run by wperl,
but this is up to you.

Since the editbin.exe is part of Microsoft's development tools and AFAWK
is not free, Jan wrote the following script that is able to do the same.

exetype c:\perl\bin\guiperl.exe WINDOWS

I've tested this both under WinNT4.0 (sp4) and Win95sp1.

An updated version of the script is now installed with ActivePerl as

You may use it to "de-consolize" any EXEcutable of course ;-)

This script was written by Jan Dubois . Thanks,
Jan :-)
use strict;
unless (@ARGV == 2) {
print "Usage: $0 exefile [CONSOLE|WINDOWS]\n";
unless ($ARGV[1] =~ /^(console|windows)$/i) {
print "Invalid subsystem $ARGV[1], please use CONSOLE or WINDOWS\n";
my ($record,$magic,$offset,$size);
open EXE, "+< $ARGV[0]" or die "Cannot open $ARGV[0]: $!"; binmode EXE; read EXE, $record, 32*4; ($magic,$offset) = unpack "Sx58L", $record; die "Not an MSDOS executable file" unless $magic == 0x5a4d; seek EXE, $offset, 0; read EXE, $record, 24; ($magic,$size) = unpack "Lx16S", $record; die "PE header not found" unless $magic == 0x4550; die "Optional header not in NT32 format" unless $size == 224; seek EXE, $offset+24+68, 0; print EXE pack "S", uc($ARGV[1]) eq 'CONSOLE' ? 3 : 2; close EXE; Automatic setup I've written a script that creates the wperl.exe (if you do not have it already) and sets the file extension mapping for extensions you specify. You may find it at You need Win32::Registry2 patch from my pages! Subprocesses If your application doesn't have a console, your subprocesses should not have one either. It would look dirty if a console flicked on the screen every time you use system() or backticks. Since build 632 of ActivePerl you may use this BEGIN { Win32::SetChildShowWindow(0) if defined &Win32::SetChildShowWindow }; to instruct Perl to hide the consoles of such processes. Author The text was written by Jan Krynicky and is based on
discussion on Perl-Win32-Users mailing list, the code is by Jan Dubois