The attached POE program works as expected under both Unix and Windows. By that I mean that the current directory is listed in the Tk window, and the Tk window stays up after the directory listing is done.
However, you may notice that in order to make it work under windows, I'm running the command dir & pause. This is because if I simply run the dir command, the whole program exits and the Tk window goes away (I want the Tk window to hang around until the user does something to make it go away).
Why is this? I put the postback('DontDie') line in there for preserving the Tk window, and it works under Unix. The postback will also work under windows when I'm not using POE::Wheel::Run to do the directory listing under a separate process. I'm guessing that adding the pause keeps the child process around, which is not really what I want to do. Is there a way to preserve the Tk window without keeping the child around?
Any thoughts or pointers is appreciated.
Thanks
-Craig
use English; use strict; use warnings; use Tk; use POE; use POE::Wheel::Run; # Setup program to run... my $PGM = 'ls'; if ($OSNAME eq 'MSWin32') { $PGM = 'dir & pause' }; #if ($OSNAME eq 'MSWin32') { $PGM = 'dir' }; # This doesn't work! print STDERR "$OSNAME PGM=$PGM\n"; my $TEXT; # Global for text widget... # Setup POE session... my $session = _poeSetup(); # Create dummy postback so the session won't die once input is done... my $subref = $session->postback('DontDie'); # Go... $poe_kernel->run(); ################# # POE Subroutines ################# sub _poeSetup { my $session = POE::Session->create( inline_states=>{ _start => \&_startUp, KidOut => \&_GetStdout, KidErr => \&_GetStderr, KidClose => \&_DoClose, }, ); return($session); } # POE Session Supporting Routines... sub _startUp { $TEXT=$poe_main_window->Scrolled('Text', -wrap=>'none')->pack; $poe_main_window->update; my $child = POE::Wheel::Run->new( Program => $PGM, StdoutEvent => 'KidOut', StderrEvent => 'KidErr', CloseEvent => 'KidClose', ); $_[KERNEL]->sig_child($child->PID, '_DoSig'); $_[HEAP]{Kids}{WID}{$child->ID} = $child; $_[HEAP]{Kids}{PID}{$child->PID} = $child; } sub _GetStdout { my ($line, $wid) = @_[ARG0, ARG1]; my $child = $_[HEAP]{Kids}{WID}{$wid}; $TEXT->insert('end', $child->PID . " OUT: $line\n"); $TEXT->see('end'); $poe_main_window->update; } sub _GetStderr { my ($line, $wid) = @_[ARG0, ARG1]; my $child = $_[HEAP]{Kids}{WID}{$wid}; $TEXT->insert('end', $child->PID . " ERR: $line\n"); $TEXT->see('end'); $poe_main_window->update; } sub _DoClose { my $wid = $_[ARG0]; my $child = $_[HEAP]{Kids}{WID}{$wid}; unless (defined $child) { print STDERR "wid $wid closed all pipes.\n"; return; } print STDERR "wid $wid closed all pipes.\n"; delete $_[HEAP]{Kids}{PID}{$child->PID}; } sub _DoSig { print STDERR "pid $_[ARG1] exited with status $_[ARG2].\n"; my $child = delete $_[HEAP]{Kids}{PID}{$_[ARG1]}; return unless defined $child; delete $_[HEAP]{Kids}{WID}{$child->ID}; }
In reply to POE::Wheel::Run & MSWin32 problem by cmv
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |