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

Reply via email to