http://www.perlmonks.org?node_id=1055786

tarunmudgal4u has asked for the wisdom of the Perl Monks concerning the following question:

Hi, I'm using below code to install and uninstall a product using msiexec. While uninstalling the product silently, a pop-up windows is triggered and blocks the uninstallation process further.

For this reason I used a separate thread and killed that thread after some time (I know this is not the proper solution but it's okay for now). When this thread is killed, it leaves some msiexec processes running (including the pop-up msiexec process).

Now, when I kill these non relevant msiexec processes using system taskkill command, perl.exe gets crashed. How can I handle this problem. Below is the code and console output -

use threads; use strict; use Config; use Win32::Process::Info; use Win32::Registry; use Sys::Info::OS; use IO::Null; use IPC::System::Simple qw(capture capturex system systemx run runx $E +XITVAL EXIT_ANY); use File::Copy; use Win32::Service; use Win32::Process; $| = 1; eval { UnInstallLUAWrapper(); }; if($@){ print "LUA uninstallation was not succeeded\n"; } else{ print "LUA uninstalled successfully\n"; } eval{ InstallLUA(); }; if($@){ print "LUA installation was not succeeded\nTrying one more time..\ +t\t"; InstallLUA(); } else{ print "LUA installed successfully\n"; } sub UnInstallLUAWrapper { killProcesses("isbew"); killProcesses("msiexec"); my $thr = threads->create( { 'context' => 'scalar', 'exit' => 'thr +ead_only' }, \&UnInstallLUA ); die "thread is not initiated\n" unless ( $thr->is_running() ); my $childthreadId = $thr->tid(); sleep(180); # my $status = $thr->join(); # print "Child thread returned with satus: [$status]\n"; eval { print "Killing child thread id: $childthreadId\t\t"; $thr->kill('KILL')->detach() if ($thr->is_running()); }; if($@){ print "failed\n\n"; } else{ print "done\n\n"; #killProcesses("postgres"); } } sub InstallLUA { my $counter; print "\nInstalling LUA..\n"; eval { killProcesses("isbew"); killProcesses ("msiexec"); }; systemx qw(msiexec /qn /i "LUA.msi" /norestart /l*v LUAInstallatio +nLogs.txt); if ($EXITVAL == 0){ print "done\n"; return 1; } else{ print "failed\n"; return 0; } } sub UnInstallLUA { $SIG{'KILL'} = sub { threads->exit(); }; my $counter; print "\nUninstalling LUA..\t\t"; eval { systemx qw(msiexec /qn /x "LUA.msi" /l*v LUAUninstallationLogs +.txt UILevel="2" CLIENTUILEVEL="2" ); }; sleep(2); until ($@ || $counter > 120) { print " ."; sleep(1); $counter++; } if ($@){ print " failed\nLUA could not be uninstalled successfully\n\n" +; } else{ print " done\nLUA uninstalled successfully\n\n"; } } sub getProcessIds { my $procName = shift; my $pi = Win32::Process::Info->new(); my @listPids; for($pi->ListPids){ my ($info) = $pi->GetProcInfo($_); push (@listPids, $_) if ($info->{CommandLine} =~ m/$procName/i +); } return @listPids; } sub killProcesses { my $processName = shift; print "Killing running $processName processes if any..\n"; my @processPids = getProcessIds("$processName"); for my $pid (@processPids){ #my $isKilled = kill -9, $pid; $^E = 0; Win32::Process::KillProcess($pid, 1); sleep(1); my $err= $^E; unless ($err){ print "Killed pid: $pid\n"; } else{ print "Failed to kill pid: $pid\n"; print "Trying to kill pid $pid one more time using taskkil +l..\t\t"; eval {system qq(Taskkill /PID $pid /F > NUL 2>&1);}; sleep(1); # until ($@ || my $counter > 2) { # sleep(1); $counter++; # } unless ($@){ print "done\n\n"; } else { die "failed\n\n"; } } } 1; }

console output-

C:\Jenkins Workspace\LUAESD\Setup>msiexec /qn /i "LUA.msi" /norestart +/l*v LUAInstal lationLogs.txt C:\Jenkins Workspace\LUAESD\Setup> C:\Jenkins Workspace\LUAESD\Setup> C:\Jenkins Workspace\LUAESD\Setup>perl temp.pl Killing running isbew processes if any.. Killing running msiexec processes if any.. Failed to kill pid: 4100 Trying to kill pid 4100 one more time using taskkill.. done Uninstalling LUA.. Killing child thread id: 1 + done LUA uninstalled successfully Installing LUA.. Killing running isbew processes if any.. Killed pid: 4332 Killing running msiexec processes if any.. Free to wrong pool 26540e0 not 2c39b8 during global destruction. Killed pid: 1712 <<<<<<< here, Perl.exe gets crashed

Replies are listed 'Best First'.
Re: Killing some processes unsing system taskkill crashes Perl.exe
by Anonymous Monk on Sep 26, 2013 at 07:39 UTC

    Without looking too close at your code (and without trying to run it) , I suspect its because of sharing STDIN/STDOUT/STDERR

    So first thing I would try is to create detached processes without inheriting any handles with system_detached

    If the popup you get is standard win32 error dialog, you can silence it on most NT5+ systems with https://metacpan.org/module/Win32API::File#SetErrorMode  use Win32API::File(); Win32API::File::SetErrorMode(2);

      Hi, thanks for your help. I created new process and tweak my code accordingly and it worked.. thanks again