The PAR tool pp has a --gui option which disables the cmd console on Windows. While more friendly, it often makes debugging a problem with an installation difficult.
After finding a reference to exetype.pl which twiddles Win32 binaries, I tried to apply it to PAR exes but it fails as PAR nests another non-console exe in the main exe. A few other hacks combined to make it possible.
The pp command is something like:
C:\>pp --gui -c par_wrap.pl -a w32_exetype.pl -a w32_mkcons.pl -a main +.pl -a other_thing.pl
a.exe is console-less but running "a.exe w32_mkcons.pl" should create an a-cons.exe that runs from the commandline and reports errors there.
w32_exetype.pl is just exetype.pl mentioned above.
par_wrap.pl allows other scripts to be run besides main.pl but will default to main.pl. One consequence is that the other scripts won't be scanned for dependencies, therefore you may need to use additional -M options.
Also, since the modified exe is in PAR_TEMP, it could be removed during a cleanup and w32_mkcons.pl would need to be rerun.
#!/usr/bin/perl -w # w32_mkcons.pl - Create a console version of the running PAR exe. # May need to be rerun if the PAR_TEMP is cleared use File::Copy; #warn `set`; warn $0; warn $^X; $ENV{PAR_PROGNAME} or die "$0 only works under PAR"; my ($exe_path, $gui_exe) = $ENV{PAR_PROGNAME} =~ m{^ (.*[\\/]) (.*)}x; (my $con_exe = $gui_exe) =~ s/\.exe$/-cons.exe/; my $gui_par = "$ENV{PAR_TEMP}/$gui_exe"; my $con_par = "$ENV{PAR_TEMP}/$con_exe"; copy("$exe_path$gui_exe" => "$exe_path$con_exe"); copy($gui_par => $con_par); my @cmd = w32_cmd('w32_exetype.pl'); # needs par_wrap.pl system(@cmd, $con_exe, 'console'); system(@cmd, $con_par, 'console'); sub w32_cmd { my $script = shift; my @cmd; # Run PAR_PROGNAME exe as the perl/parl interpreter and # let bin/par_wrap.pl run $script @cmd = ($ENV{PAR_PROGNAME}, $script); return @cmd; } __END__
# par_wrap.pl # This file is a merging of the stub scripts in PAR::Packer # in the subs _main_pl_multi and _main_pl_single # It defaults to running main.pl but if the first arg ends in .pl # then we look for another script to run my $file = 'main.pl'; $file = shift if $ARGV[0] =~ /\.pl$/; my $zip = $PAR::LibCache{$ENV{PAR_PROGNAME}} || Archive::Zip->new(__FI +LE__); my $member = eval { $zip->memberNamed($file) || $zip->memberNamed("$file.pl") || $zip->memberNamed("bin/$file") || $zip->memberNamed("bin/$file.pl") || $zip->memberNamed("script/$file") || $zip->memberNamed("script/$file.pl") } or die qq(Can't open perl script "$file": No such file or dire +ctory); PAR::_run_member($member, 1); __END__
|
|---|