The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Win32::JobAdd - Add subprocesses to a "job" environment.

SYNOPSIS

   use Win32::JobAdd;

   my $job = createJobObject( 'job_foo' );
   my $pid = open O, q[perl -E "system 1, 'calc.exe';
                                system 1, 'notepad.exe';
                                sleep 100" |] or die $^E;

   assignProcessToJobObject( $job, $pid );

   # do something with the subprocess

   closeHandle( $job );

PLATFORMS

Win32::JobAdd requires Windows XP or later. Windows 95, 98, NT, Me and 2000 are not supported.

DESCRIPTION

A "job" is a collection of processes which can be controlled as a single unit. For example, you can reliably kill a process and all of its children by launching the process in a job, then telling Windows to kill all processes in the job.

There is another module Win32::Job which is fine when you don't need to do anything with the processes it spawns for you, but is limited otherwise.

With Win32::JobAdd you can create processes in a job environment and e.g. read the STDOUT from them.

See the EXAMPLE section for a useful scenario.

FUNCTIONS

JOB createJobObject JOB_NAME
   my $job = createJobObject( 'job_foo' );

Returns a JOB named JOB_NAME if it succeeds. Returns zero if it fails. Look at $^E for more detailed error information.

assignProcessToJobObject JOB PID
   assignProcessToJobObject( $job, $pid );

Assigns a PID (process ID) to the JOB. This means that the process and all its children are now part of this JOB. Returns nonzero if it succeeds. Returns zero if it fails.

closeHandle JOB
      closeHandle( $job );

Kills all processes and all its children which are part of the JOB. Returns nonzero if it succeeds. Returns zero if it fails.

EXAMPLE

The following code shows a non-blocking Tk GUI which reads from a child process which spawns another process. When pressing the "CANCEL" button or when the GUI is closed, the whole process tree is killed.

Without adding the child process to a job the grandchild process "calc" would still be alive and stay as a zombie process.

    #!/usr/bin/perl

    use strict;
    use threads;
    use Thread::Queue;

    use Win32::JobAdd;

    ## A shared var to communicate progess between work thread and TK
    my $Q = new Thread::Queue;

    my $job:shared = createJobObject( 'counter_and_calc_job' );

    sub work{
        my $pid = open PROC,
        q[perl -le "$|=1; system 1, 'calc.exe'; print and select(undef,undef,undef,0.1) for 1 .. 1000" |]
            or die $!;
        assignProcessToJobObject( $job, $pid );

        while( <PROC> ) {
            $Q->enqueue( $_ );
        }
        close PROC;
    }

    threads->new( \&work )->detach;

    ## For lowest memory consumption require (not use)
    ## Tk::* after you've started the work thread.
    require Tk::ProgressBar;

    my $mw = MainWindow->new;
    my $pb = $mw->ProgressBar()->pack();
    my $button = $mw->Button(-text => 'CANCEL',
                             -command => sub { closeHandle( $job ) } )->pack();

    my $repeat;
    $repeat = $mw->repeat( 100 => sub {
        while( $Q->pending ) {
            my $progress = $Q->dequeue;
            return unless $progress;
            $repeat->cancel if $progress == 100;
            $pb->value( $progress )
        }
    });

    $mw->MainLoop;

SEE ALSO

For more information about jobs, see Microsoft's online help at

   http://msdn.microsoft.com/

For another module which does a similar thing, see:

Win32::Job

Run subprocesses in a job environment. See Win32::Job.

AUTHOR

BrowserUk (browseruk@cpan.org) Dirk Joos (dirk@dirkundsari.de)

COPYRIGHT

Copyright (c) 2012, BrowserUk, Dirk Joos. All Rights Reserved. This program is free software; you may use it and/or redistribute it under the same terms as Perl itself.