Malcolm Nooning wrote:
Hello,

How can I identify the bundled perl binary from within a pp created executable? Perl will NOT be installed on the end user's machine.

Specifically, I would like to do something like this:

Win32::Process::Create($ProcessObj,
                           "full_path_to_the_by now_unwrapped_perl.exe",
                           "perl.exe   bundled_perl_file.pl",
                           0,
                           NORMAL_PRIORITY_CLASS,
                           ".")|| die ErrorReport();

I have need for one process to watch another and kill it if there is a problem. Since I use Tk, which is not thread safe, I cannot use the Windows fork (Perl 5.8.8 + fork + Tk worked on Windows XP but not on Windows 2000).

Another solution would be to create a separate pp'd .exe to be executed as the Win32::Process::Create invoked process. However, the extra time taken up in the initial unwrapping/unbundling, etcetera, would seem unpalatable. That is why I am hoping for a scheme wherein I could use the by-then already unbundled perl.exe.

A quick search reveals that there is no perl.exe anywhere under the par-malcolm directory. My next question is then ... how could my end goal be reached?

Thanks


------------------------------
I would like to continue this request for assistance, as I have made some progress. I think that if I could get this to work it would open up a lot of areas for PAR/pp.

I would like to have two emails, this one and the next. This first one outlines how the end goal can be reached by having one .exe invoke another. Since it works, albeit more slowly than desired, I will just post this and forget about it.

My next email will show where I am stuck trying to have a faster implementation.

For those that might get along fine with one exe invoking another, a
"test_minus_a_invoked.exe" can be created, along with an "invoked.exe", wherein invoked.exe is invoked within test_minus_a_invoked.exe. The command lines and the reasoning are shown below. This assumes that the working directory is c:\aaa.

pp -o invoked.exe invoked.pl  # Nothing new here

pp -o test_invoked_from_cache.exe -a "c:/perl/bin/perl.exe;inc/../../perl.exe" -a "c:/aaa/invoked.exe;invoked.exe" test_invoked_from_cache.pl

Above I am taking C:/perl/bin/perl.exe and putting it into the top level directory where the perl.dll is normally placed. I do not know if it is really necessary, but that is what I did.

The business of
"c:/perl/bin/perl.exe;inc/../../perl.exe" is there instead of, say,
"c:/perl/bin/perl.exe;/perl.exe"
because just using "/perl.exe" did not seem to work, so I think I had to trick pp a little to get it into the upper level cache directory.

The
-a "c:/aaa/invoked.exe;invoked.exe"
puts invoked.exe into .../cache-xxx/inc/invoked.exe.

From here, assuming I have the fully qualified path name to the cache directory from within test_invoked_from_cache, I can do this within test_minus_a_invoked.pl

my $fqpn_invoked = File::Spec->catfile( $par_base,
                                        "inc",
                                        "invoked.exe",
                                      );

if (system(" \"$fqpn_invoked\" ")) {
  die("100 OUCH\n");
} else {
  print("105 Success \n");
}

You may well ask, just how can we know the cache directory? Here is the way I did it. Does anyone know an easier way?

------------- paste sub
sub find_par_temp_base {
  my ($debug) = @_;

  #################################################################
  # Originally taken from par.pl:_set_par_temp.  The lines
  # containing $Config{_delim} were replaced by
  # File::Spec->catdir(whatever, whatever);
  #################################################################
  my $path = "";
  my $par_temp = "";
  my $progname = "";
  my $username = "";
  my $stmpdir = "";
  my $mtime = "";
  my $ctx = "";

    print("msg210:\n") if $debug;
    if ($ENV{PAR_TEMP} and $ENV{PAR_TEMP} =~ /(.+)/) {
        $par_temp = $1;
        print("msg215: Returning $par_temp\n") if $debug;
        return ($par_temp);
    }

    foreach $path (
        (map $ENV{$_}, qw( TMPDIR TEMP TMP )),
        qw( C:\\TEMP /tmp . )
    ) {
        next unless $path and -d $path and -w $path;
        $username = defined(&Win32::LoginName)
            ? &Win32::LoginName()
            : $ENV{USERNAME} || $ENV{USER} || 'SYSTEM';

        $stmpdir = File::Spec->catdir($path, "par-$username");
        last;
    }
    print ("msg270: stmpdir is $stmpdir\n") if $debug;

    return ($stmpdir);
}
-------------- end paste sub
and then do:

my $par_base = find_par_temp_base(0);


So there it is. The above was just a proof-of-concept so that one can have a system command that utilized the already bundled up perl.

But what if you had a parent/child application? The code below also worked. I pasted it just after the already stated "system" command.

-------------paste this also worked
my $ProcessObj;
my $exitcode = "";

Win32::Process::Create($ProcessObj,
                       $fqpn_invoked,
                       "invoked.exe",
                       0,
                       NORMAL_PRIORITY_CLASS,
                       ".")|| die ("Phooey:$!:\n");
sleep(2);
print("This is the parent just after waiting for the child\n");
$ProcessObj->Kill($exitcode);
--------------end paste this also worked




Reply via email to