processhelp.pm: use Win32::Process* perl modules if available

`Win32::Process::List` and `Win32::Process`.

To replace external calls to `tasklist.exe` and `taskkill.exe`.

The perl modules are more efficient by not launching a command shell
(including MSYS2) and an external process, then parse their output.

According to local tests and the CI, one test session calls
`tasklist.exe` 350-400 times. `taskkill.exe` is rarely called and often
not called at all:
https://github.com/curl/curl/actions/runs/17012376726?pr=18296

Cherry-picked from #18296
This commit is contained in:
Viktor Szakats 2025-08-18 10:28:42 +02:00
parent 294ebba565
commit f3e5a66a6c
No known key found for this signature in database
GPG key ID: B5ABD165E2AEF201

View file

@ -29,6 +29,12 @@ use warnings;
use Time::HiRes;
use pathhelp qw(
os_is_win
);
my $has_win32_process;
BEGIN {
use base qw(Exporter);
@ -43,6 +49,18 @@ BEGIN {
set_advisor_read_lock
clear_advisor_read_lock
);
if(os_is_win() && $^O ne 'MSWin32') {
$has_win32_process = eval {
no warnings "all";
# https://metacpan.org/pod/Win32::Process
require Win32::Process;
# https://metacpan.org/pod/Win32::Process::List
require Win32::Process::List;
};
} else {
$has_win32_process = 0;
}
}
use serverhelp qw(
@ -51,10 +69,6 @@ use serverhelp qw(
datasockf_pidfilename
);
use pathhelp qw(
os_is_win
);
use globalconfig qw(
$dev_null
);
@ -114,11 +128,18 @@ sub pidexists {
if($pid > 4194304 && os_is_win()) {
$pid -= 4194304;
if($^O ne 'MSWin32') {
my $filter = "PID eq $pid";
# https://ss64.com/nt/tasklist.html
my $result = `tasklist -fi \"$filter\" 2>$dev_null`;
if(index($result, "$pid") != -1) {
return -$pid;
if($has_win32_process) {
my %processes = Win32::Process::List->new()->GetProcesses();
if(exists $processes{$pid}) {
return -$pid;
}
} else {
my $filter = "PID eq $pid";
# https://ss64.com/nt/tasklist.html
my $result = `tasklist -fi \"$filter\" 2>$dev_null`;
if(index($result, "$pid") != -1) {
return -$pid;
}
}
return 0;
}
@ -145,10 +166,14 @@ sub pidterm {
if($pid > 4194304 && os_is_win()) {
$pid -= 4194304;
if($^O ne 'MSWin32') {
# https://ss64.com/nt/taskkill.html
my $cmd = "taskkill -f -t -pid $pid >$dev_null 2>&1";
print "Executing: '$cmd'\n";
system($cmd);
if($has_win32_process) {
Win32::Process::KillProcess($pid, 0);
} else {
# https://ss64.com/nt/taskkill.html
my $cmd = "taskkill -f -t -pid $pid >$dev_null 2>&1";
print "Executing: '$cmd'\n";
system($cmd);
}
return;
}
}
@ -170,10 +195,14 @@ sub pidkill {
if($pid > 4194304 && os_is_win()) {
$pid -= 4194304;
if($^O ne 'MSWin32') {
# https://ss64.com/nt/taskkill.html
my $cmd = "taskkill -f -t -pid $pid >$dev_null 2>&1";
print "Executing: '$cmd'\n";
system($cmd);
if($has_win32_process) {
Win32::Process::KillProcess($pid, 0);
} else {
# https://ss64.com/nt/taskkill.html
my $cmd = "taskkill -f -t -pid $pid >$dev_null 2>&1";
print "Executing: '$cmd'\n";
system($cmd);
}
return;
}
}