use strict;
use warnings;
use Win32::Process;
use Win32;
use Data::Dumper;
my $netstat_obj;
my $create_status = Win32::Process::Create(
$netstat_obj,
'C:/Windows/System32/netstat.exe', 'netstat -a -e -n -o -s -r'
+,
0, DETACHED_PROCESS | CREATE_NO_WINDOW | CREATE_SUSPENDED,
'C:/temp/' ) || die Win32::FormatMessage(Win32::GetLastError()
+);
print Data::Dumper->new(['1', $create_status, $netstat_obj], ['where__
+________', 'create_status', 'netstat_obj'])->Indent(1)->Sortkeys(1)->
+Useqq(1)->Deparse(1)->Dump();
my $NETSTAT_FH;
my $open_status = Win32::Process::Open(
$NETSTAT_FH,
$netstat_obj->GetProcessID(),
0 ) || die Win32::FormatMessage(Win32::GetLastError());
print Data::Dumper->new(['2', $open_status, $NETSTAT_FH], ['where_____
+_____', 'open_status', 'NETSTAT_FH'])->Indent(1)->Sortkeys(1)->Useqq(
+1)->Deparse(1)->Dump();
$netstat_obj->Resume();
my $netstat_data = '';
{
my $offset = 0;
my $length = 1024;
my $buffer = undef;
while(my $bytes_read = $NETSTAT_FH->sysread($buffer, $length, $offse
+t)) {
if(defined $bytes_read) {
$netstat_data .= $buffer;
$buffer = undef;
last if($bytes_read == 0);
$offset += $bytes_read;
}
else { die "ERROR: Could not read from NETSTAT_FH: $! "; }
}
}
$netstat_obj->Wait(2000);
my $netstat_exit;
$netstat_obj->GetExitCode($netstat_exit);
print Data::Dumper->new(['3', $netstat_obj, $NETSTAT_FH, $netstat_data
+], ['where__________', 'netstat_obj', 'NETSTAT_FH', 'netstat_data'])-
+>Indent(1)->Sortkeys(1)->Useqq(1)->Deparse(1)->Dump();
The results of running the above code:
C:\temp>perl.exe sandbox.pl
$where__________ = 1;
$create_status = 1;
$netstat_obj = bless( do{\(my $o = 1776208)}, 'Win32::Process' );
$where__________ = 2;
$open_status = 1;
$NETSTAT_FH = bless( do{\(my $o = 1777552)}, 'Win32::Process' );
Your vendor has not defined Win32::Process macro sysread, used at sand
+box.pl line 32. (Error was: 'Invalid argument')
at C:/xampp/perl/site/lib/Win32/Process.pm line 53.
What I am trying to do in the above code is:
- create a new (detached and suspended) Windows process sans command window
- open a filehandle to the newly created process for reading said process's STDOUT
- read all of the data from the filehandle
- and wait for netstat to exit, then find its exit code
As the above output demonstrates, I am stuck on #3 (and despite the
CREATE_NO_WINDOW constant, a window is
still being created :-/ ).
In place of the sysread, I have tried: read, getlines, and getline; all with the same error "Your vendor has not defined Win32::Process macro X, used at …", where X is one of the aforementioned methods.