Thanks,
I found this which did exactly what I want -
Use Win32::Iproc # Available from Jenda Krynicky
my($obj)=new Win32::IProc || die;
$obj->EnumProcesses([EMAIL PROTECTED],"NOPATH");
foreach $Process (@EnumInfo) {
print $Process->{ProcessName}."\n";
}
Thanks for your help,
Darin
--------------------------------------------
Darin Cruickshanks
Labs Manager, Computing Service
University of Essex
[EMAIL PROTECTED]
01206 873585
-----Original Message-----
From: $Bill Luebkert [mailto:[EMAIL PROTECTED]
Sent: 19 November 2003 11:26
To: Cruickshanks, Darin
Cc: [EMAIL PROTECTED]
Subject: Re: List all Processes
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