1

Hello pips,

I have a Tkx gui which runs a batch file using button. The batch file is executed in a different thread, cause I want the GUI to still be usable. I want to implement a cancel button to cancel the execution of the batch file.

I tried sending a Kill signal but it will only terminate the thread and not the batch file. Below are the codes for the run and cancel subroutines.

Oh and I am not allowed to edit the batch file.

my $t1;
sub runbutton{
    $bar->g_grid();
    $bar->start();
    $t1 = threads->create(sub { 
        local $SIG{'KILL'} = sub { threads->exit };
        system("timer.bat"); 
        
        });
    
    $t1->set_thread_exit_only(1);
    my $start = time;
    my $end = time;
    while ($t1->is_running()) { 
        $end = time();
        $mytext = sprintf("%.2f\n", $end - $start);
        Tkx::update(); 
   }
   
    $bar->stop();
    $bar->g_grid_forget();
    $b4->g_grid_forget();
}

sub cancelbutton
{
    $t1->kill('KILL')->detach();
}
Community
  • 1
  • 1
rezeile
  • 41
  • 7

2 Answers2

1

You are running this on windows, since you say 'batch'?

I believe you'll have to 'identify' and 'kill' the process using OS-specific tools, e.g. pslist/pskill (sysinternals)

lexu
  • 8,766
  • 5
  • 45
  • 63
0

I suspect that the Perl thread is waiting for system to return before "firing" the kill signal is executed.

I would suggest using Win32::Process to start the batch file as a separate process and then have a variable to signal the process should be terminated. When the variable is set, the thread can kill the process and then exit.

Here is the small test case I used to check it out using Win::Process to create and kill a batch file as a separate process using Active State Perl Version 5.16.1:

use strict;

# Modules needed for items
use Win32::Process;
use Win32;

# Subroutine to format the last error message which occurred
sub ErrorReport
{
    print Win32::FormatMessage( Win32::GetLastError() );
}

print "Starting Process\n";

# Declare a scalar for the process object
my $ProcessObj;

# Create the process to run the batch file
Win32::Process::Create($ProcessObj,
    "C:\\Users\\Glenn\\temp.bat",
    "C:\\Users\\Glenn\\temp.bat",0,
    NORMAL_PROIRITY_CLASS,
    ".") || ErrorReport();

print "Process Started\n";

# Sleep for a few seconds to let items start running
sleep(2);

# Kill the process with a -9
# $ProcessObj->Kill(0) does not seem to work to stop the 
# process.  Kill will kill the process with the process id 
kill -9,$ProcessObj->GetProcessID();

# Done with efforts
print "Complete\n";

If you are using Windows 7, you will need to run as administrator to allow the process to be created, otherwise you will get an Access Denied message when trying to create the process.

Glenn
  • 1,169
  • 1
  • 14
  • 23