in reply to Re: Windows cmd.exe output -> Tk text widget?
in thread Windows cmd.exe output -> Tk text widget?

use Tk; use IPC::Open3; use IO::Handle; use Win32::Process::Kill; use threads; use threads::shared; use Thread::Queue; $q=Thread::Queue->new; $qe=Thread::Queue->new; unlink('out.txt'); my %font=(-font=>[-family=>'Courier New',-size=>10]); my %width=(-width=>120); $pid = open3( \*CHILD_IN, \*CHILD_OUT, \*CHILD_ERR, 'cmd.exe' ); print "pid = $pid\n"; sleep(1); threads->create(\&handle_child_out)->detach; threads->create(\&handle_child_err)->detach; print "threads created\n"; autoflush CHILD_OUT; autoflush CHILD_ERR; my %font=(-font=>[-family=>'Courier New',-size=>10]); my %width=(-width=>118); my $mw=new MainWindow; my $entry=$mw->Entry( %width, -relief=>'groove', -borderwidth=>5, -textvariable=>\$entry_text, %font )->pack; $entry->focus; $entry->bind('<Key-Return>',\&enter); my $text=$mw->Scrolled('Text', -insertontime=>0, -scrollbars=>'e', %font, %width, -height=>43 )->pack; my $geom=$mw->geometry; $geom='+5+5'; $mw->geometry($geom); $mw->after(500,\&handler); MainLoop; Kill($pid); sub enter { print CHILD_IN "$entry_text\n"; $entry_text=''; $entry->focus; } sub handler { while(($q->pending)||($qe->pending)) { my ($content,$contente); if($q->pending) { $content=$q->dequeue; $content=~s/\r//g; } if($qe->pending) { $contente=$qe->dequeue; $contente=~s/\r//g; } my ($x,$y)=$text->yview(); $text->insert('1.0',"$content$contente"); $text->yview(moveto=>$x); $entry->focus; } $mw->after(500,\&handler); } sub handle_child_out { sleep(1); do { sysread CHILD_OUT, $content, 4092; if($content ne '') { $q->enqueue($content); } } while(1); } sub handle_child_err { sleep(1); do { sysread CHILD_ERR, $content, 4092; if($content ne '') { $q->enqueue($content); } } while(1); }

Replies are listed 'Best First'.
Re^3: Windows cmd.exe output -> Tk text widget?
by zentara (Cardinal) on Feb 10, 2012 at 12:37 UTC
      Look: this is not an issue. IPC::Open3 works fine on Windows. What does not work on Windows is a non-blocking read on file handles and any kind of solution which boils down to 'timeout' or 'can read' with respect to filehandles. The thing you have to do is to create threads to perform blocking reads on filehandles. If this is done in a Tk application you should avoid joining your threads before you quit the main loop unless you want to crash miserably. If you adhere to these precautions you can write a multi threaded process piping Tk application under Windows in a safe way. I have learned the lessons well because I have a quite complicated Tk application which monitors and sends command to heavy external processes. The issue here is with code pages however this I've already resolved in a separate node.