Cruickshanks, Darin wrote:
> Hi,
>
> Does anyone know of an easy way to list all the running processes on the
> local machine with Perl?
Here are several versions :
WMI version:
#!perl -w --
use strict;
use Win32::OLE;
use Data::Dumper; $Data::Dumper::Indent=1;
our %A; # get commandline switches into %A
for (my $ii = 0; $ii < @ARGV; ) {
last if $ARGV[$ii] =~ /^--$/;
if ($ARGV[$ii] !~ /^-{1,2}(.*)$/) { $ii++; next; }
my $arg = $1; splice @ARGV, $ii, 1;
if ($arg =~ /^([\w]+)=(.*)$/) { $A{$1} = $2; } else { $A{$1}++; }
}
my $node = Win32::NodeName;
my $debug = $A{d} || 0;
my $remote = $A{r} ? $A{r} : $node;
my $short = $A{s} || 0;
my $verbose = $A{v} || 0;
# possible properties of Win32_Process :
# Caption CreationClassName CreationDate CSCreationClassName CSName Description
# ExecutablePath ExecutionState Handle HandleCount InstallDate KernelModeTime
# MaximumWorkingSetSize MinimumWorkingSetSize Name OSCreationClassName OSName
# OtherOperationCount OtherTransferCount PageFaults PageFileUsage
# ParentProcessId PeakPageFileUsage PeakVirtualSize PeakWorkingSetSize Priority
# PrivatePageCount ProcessId QuotaNonPagedPoolUsage QuotaPagedPoolUsage
# QuotaPeakNonPagedPoolUsage QuotaPeakPagedPoolUsage ReadOperationCount
# ReadTransferCount SessionId Status TerminationDate ThreadCount UserModeTime
# VirtualSize WindowsVersion WorkingSetSize WriteOperationCount
# WriteTransferCount
# set up for PS list and Win32_Process - properties I want to list
my %want = ( # 0 for number; 1 for string
ExecutablePath => 1,
Name => 1,
Priority => 0,
ProcessId => 0,
ThreadCount => 0,
);
my $class = shift || 'Win32_Process';
die "\nUsage: $0 [-r=<machine>] [-s]\n\ts\tshort line version\n\n" if $A{h} or
$A{help};
Win32::OLE->Option ('Warn' => 3);
# Get a handle to the SWbemServices object of the machine.
print qq{GetObject ("WinMgmts://$remote/")\n} if $debug;
my $computer = Win32::OLE->GetObject("WinMgmts://$remote/");
# Get the SWbemObjectSet of all objects of the class.
print qq{InstancesOf($class)\n} if $debug;
my $objs = $computer->InstancesOf($class);
# Convert set to Perl array.
print qq{Enum->All(objs)\n} if $debug;
my @objs = Win32::OLE::Enum->All($objs);
print 'Found ', scalar @objs, " objects\n" if $debug;
# print title line
printf "%3s %3s %6s %-12s on computer: %s\n", 'Pri', 'Thr', 'PID',
$short ? 'Name' : 'ExePath', $remote;
my @pos = qw(0 1 2 3);
my @titles = qw(Priority ThreadCount ProcessId);
if (not $short) {
push @titles, 'ExecutablePath';
} else {
push @titles, 'Name';
}
my @width = ('%3s ', '%3s ', '%10s ', '%-10s'); # , '%-8s');
# Pri Thr PID ExePath on computer: FUBAR
# 0 1 0 <undef>
# 8 9 484 D:\WINDOWS\System32\mqtgsvc.exe
my @lines;
foreach my $obj (@objs) {
my $line = get_properties ($obj);
push @lines, $line;
}
print @lines if $debug;
my @sorted = map { $_->[0] } sort { $a->[3] <=> $b->[3] }
map { [ $_, split /\|/ ] } @lines;
foreach (@sorted) {
my @flds = split /\|/;
for (my $ii = 0; $ii < @titles; $ii++) {
printf $width[$ii], $flds[$pos[$ii]];
}
print "\n";
}
exit 0;
#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
sub get_properties {
my $node = shift;
print Data::Dumper->Dump([$node], [qw($node)]) if $debug and $verbose;
my @objs = (Win32::OLE::Enum->All($node->{Properties_}));
print "\n", scalar @objs, " objects\n" if $debug;
my %hash = ();
foreach my $obj (@objs) {
print Data::Dumper->Dump([$obj], [qw($obj)]) if $debug and $verbose;
our $ref;
eval { $ref = ref $obj->{Value}; };
next if not defined $ref;
my $name = $obj->{Name};
my $type = $want{$name}; # 0 = number; 1 = string
$type = 1 if not defined $type;
if (ref ($obj->{Value}) eq "ARRAY") {
my $vals = $obj->{Value};
print scalar @$vals, " values\n" if $debug;
my $first = 0;
foreach my $value (@$vals) {
$value =~ s/^\s+|[\000\s]*$//g;
$hash{$name} .= ', ' if $first++;
defined $value or $value = ($type == 1 ? '<undef>' : 0);
$hash{$name} .= $value;
}
} else {
next if defined $name and not exists $want{$name} and
not $debug;
my $value = $obj->{Value} || ($type == 1 ? '<undef>' : 0);
$value =~ s/^\s+|[\000\s]*$//g;
$hash{$name} = $value;
print "$name -> $value\n" if $debug;
}
}
my $line = '';
my $first = 0;
for (my $ii = 0; $ii < @titles; $ii++) {
$line .= '|' if $first++;
$line .= $hash{$titles[$ii]};
}
return $line;
}
__END__
If you have Win32::Process::Info you can play with this :
use strict;
use Win32::Process::Info;
#my $use_NT = 0;
my $use_NT = 1;
#my $sort = 'ProcessId';
my $sort = 'Name';
#my $type = 'N';
my $type = 'A';
my $pi = new Win32::Process::Info(undef, 'NT');
my @procs = $pi->GetProcInfo();
print Data::Dumper->Dump([EMAIL PROTECTED], [qw(@procs)]) if $debug;
my @WMI_names = qw(
CSCreationClassName CSName Caption CommandLine CreationClassName
CreationDate Description ExecutablePath ExecutionState Handle HandleCount
InstallDate KernelModeTime MaximumWorkingSetSize MinimumWorkingSetSize Name
OSCreationClassName OSName OtherOperationCount OtherTransferCount Owner
OwnerSid PageFaults PageFileUsage ParentProcessId PeakPageFileUsage
PeakVirtualSize PeakWorkingSetSize Priority PrivatePageCount ProcessId
QuotaNonPagedPoolUsage QuotaPagedPoolUsage QuotaPeakNonPagedPoolUsage
QuotaPeakPagedPoolUsage ReadOperationCount ReadTransferCount SessionId Status
TerminationDate ThreadCount UserModeTime VirtualSize WindowsVersion
WorkingSetSize WriteOperationCount WriteTransferCount
);
my @NT_names = qw(
CreationDate ExecutablePath KernelModeTime MaximumWorkingSetSize
MinimumWorkingSetSize Name OtherOperationCount OtherTransferCount Owner
OwnerSid ProcessId ReadOperationCount ReadTransferCount UserModeTime
WriteOperationCount WriteTransferCount _status
);
if ($type eq 'N') {
print "Using numeric sort on $sort\n";
foreach my $hash (sort { \$a->{$sort} <=> \$b->{$sort} } @procs) {
print "\n";
printf "%s => '%s':\n", 'PID', $hash->{ProcessId} || '<undef>';
if ($use_NT) {
foreach (@NT_names) {
printf "\t%s => '%s'\n", $_,
$hash->{$_} || '<undef>';
}
} else {
foreach (@WMI_names) {
printf "\t%s => '%s'\n", $_,
$hash->{$_} || '<undef>';
}
}
}
} else {
print "Using alpha sort on $sort\n";
foreach my $hash (sort { \$a->{$sort} cmp \$b->{$sort} } @procs) {
print "\n";
printf "%s => '%s':\n", 'Name', $hash->{Name} || '<undef>';
if ($use_NT) {
foreach (@NT_names) {
printf "\t%s => '%s'\n", $_,
$hash->{$_} || '<undef>';
}
} else {
foreach (@WMI_names) {
printf "\t%s => '%s'\n", $_,
$hash->{$_} || '<undef>';
}
}
}
}
__END__
Win32::PerfLib version :
use strict;
use Win32::PerfLib;
my $server = '';
my %counter;
Win32::PerfLib::GetCounterNames ($server, \%counter);
my %r_counter = map { $counter{$_} => $_ } keys %counter;
# retrieve the obj and id for process object
my $process_obj = $r_counter{Process};
my $process_id = $r_counter{'ID Process'};
# create connection to $server
my $perflib = new Win32::PerfLib($server);
# get the performance data for the process object
my $proc_ref = {};
$perflib->GetObjectList($process_obj, $proc_ref);
$perflib->Close();
my $instance_ref = $proc_ref->{Objects}->{$process_obj}->{Instances};
foreach my $p (sort keys %{$instance_ref}) {
my $counter_ref = $instance_ref->{$p}->{Counters};
foreach my $i (keys %{$counter_ref}) {
if ($counter_ref->{$i}->{CounterNameTitleIndex} ==
$process_id) {
printf "% 6d %s\n", $counter_ref->{$i}->{Counter},
$instance_ref->{$p}->{Name};
}
}
}
__END__
OLE version - could use some better formatting :
use strict;
use Win32::OLE;
# Get a property, returning the empty string if it does not exist.
# (The "CommandLine" property is new with Windows XP.)
sub get_property ($$) {
my ($obj, $prop) = @_;
my $old_warn = Win32::OLE->Option ('Warn');
Win32::OLE->Option('Warn' => 0);
my $val = $obj->{$prop};
Win32::OLE->Option('Warn' => $old_warn);
return (defined $val ? $val : '');
}
sub by_pid ($$) {
my ($proc1, $proc2) = @_;
return (get_property ($proc1, 'ProcessId') <=>
get_property ($proc2, 'ProcessId'));
}
Win32::OLE->Option('Warn' => 3);
# Get a handle to the SWbemServices object of the local machine.
my $computer = Win32::OLE->GetObject('WinMgmts:');
# Get the SWbemObjectSet of all processes.
my $processes_set = $computer->InstancesOf('Win32_process');
# Convert set to a Perl array.
my @processes = Win32::OLE::Enum->All ($processes_set);
foreach my $process (sort by_pid @processes) {
my ($pid, $ppid, $name, $cmdline) = (map {
get_property ($process, $_) } ('ProcessId', 'ParentProcessId',
'Name', 'CommandLine'));
printf "pid=%5s ppid=%5s name=%-16s cmdline=%s\n", $pid, $ppid, $name,
$cmdline;
}
__END__
--
,-/- __ _ _ $Bill Luebkert Mailto:[EMAIL PROTECTED]
(_/ / ) // // DBE Collectibles Mailto:[EMAIL PROTECTED]
/ ) /--< o // // Castle of Medieval Myth & Magic http://www.todbe.com/
-/-' /___/_<_</_</_ http://dbecoll.tripod.com/ (My Perl/Lakers stuff)
_______________________________________________
Perl-Win32-Admin mailing list
[EMAIL PROTECTED]
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs