Forum: Ruby Getting a list of Processes

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
ReggW (Guest)
on 2006-06-10 19:11
How do you get a list of running Processes using Ruby?

P.S. I'm on Windows

Thanks
Daniel B. (Guest)
on 2006-06-10 19:24
(Received via mailing list)
ReggW wrote:
> How do you get a list of running Processes using Ruby?
>
> P.S. I'm on Windows
>
> Thanks
>

require 'sys/proctable'
include Sys

ProcTable.ps{ |proc_struct|
    p proc_struct
}

Regards,

Dan
ReggW (Guest)
on 2006-06-11 02:18
Daniel B. wrote:
> ReggW wrote:
>> How do you get a list of running Processes using Ruby?
>>
>> P.S. I'm on Windows
>>
>> Thanks
>>
>
> require 'sys/proctable'
> include Sys
>
> ProcTable.ps{ |proc_struct|
>     p proc_struct
> }
>

This fails immediately for me with "no such file to load --
sys/proctable"

Does this mean that I'm missing something that is not part of the Ruby
core?

Thanks
Daniel B. (Guest)
on 2006-06-11 02:28
(Received via mailing list)
ReggW wrote:
>>
>
> Thanks
>

The sys-proctable package is on the RAA (http://raa.ruby-lang.org).
It's not part of the stdlib.

Regards,

Dan
Ben N. (Guest)
on 2006-06-11 07:18
(Received via mailing list)
> >>>
> >>> P.S. I'm on Windows
> >>>
> >>> Thanks
> >>>
> >> require 'sys/proctable'
> >> include Sys
> >>
> >> ProcTable.ps{ |proc_struct|
> >>     p proc_struct
[...]

I don't know what you're trying to do, but here's some hackjob code to
do it
using Win32API. The basic method is to create a Toolhelp32 snapshot and
then
enumerate the processes using Process32First and Process32Next.

---
require 'Win32API'

# some constants
TH32CS_SNAPPROCESS=0x00000002
Proc32Size=(9*4)+260 # 9 DWORDS plus a string of length MAX_PATH
(default
260)

class ProcessEntry32
	attr_reader :size, :usage, :pid, :default_heap, :module_id,
:threads, :parent_pid, :base_priority, :flags, :name
	def initialize( raw_entry )
		@size=raw_entry[0..3].unpack('I').first
		@usage=raw_entry[4..7].unpack('I').first #MDSN: always zero
		@pid=raw_entry[8..11].unpack('I').first
		@default_heap=raw_entry[12..15].unpack('I').first # MSDN:
always zero
		@module_id=raw_entry[16..19].unpack('I').first # MSDN:
always zero
		@threads=raw_entry[20..23].unpack('I').first
		@parent_pid=raw_entry[24..27].unpack('I').first
		@base_priority=raw_entry[28..31].unpack('I').first
		@flags=raw_entry[32..35].unpack('I').first # MSDN: always
zero
		@name=raw_entry[36..@size-1].split("\0").first
	end
end

CreateToolhelp32Snapshot=Win32API.new("kernel32","CreateToolhelp32Snapshot",
'LL','L')
Process32First=Win32API.new("kernel32","Process32First",'LP','L')
Process32Next=Win32API.new("kernel32","Process32Next",'LP','L')

snaphandle=CreateToolhelp32Snapshot.Call(TH32CS_SNAPPROCESS,0)
procentryraw="\0"*Proc32Size
procentryraw[0..3]=int2raw(Proc32Size) # need to initialise size or
Process32First will fail
# int2raw is a little helper function I wrote when first learning,
# to convert an int into a DWORD. The core is:
# ("%.8x"%unsigned_int).scan(/../).reverse.map {|b| b.hex}.pack('cccc')
# but there is bound to be a nicer way to do it, so don't copy it. ;)

processes=[]
if Process32First.Call(snaphandle,procentryraw)
	processes.push(ProcessEntry32.new(procentryraw))
else
	fail "horribly"
end
while Process32Next.call(snaphandle,procentryraw) == 1
	processes.push(ProcessEntry32.new(procentryraw))
end

processes.sort {|x,y| x.parent_pid <=> y.parent_pid}.each do |process|
[do stuff]
---

I'm sure that more experienced rubyists can correct my idiomatic usage.
Win32API is scarcely documented, so maybe this will come in handy for
someone at some point.

Cheers,

ben
(Guest)
on 2006-06-11 12:35
(Received via mailing list)
ReggW wrote:
> How do you get a list of running Processes using Ruby?
>
> P.S. I'm on Windows
>

one thing *not* to do: use "$$" to get PID, took me a long time to
figure out what that was when i saw it a few months back.
Brad (Guest)
on 2006-06-11 16:47
ReggW wrote:
> How do you get a list of running Processes using Ruby?
>
> P.S. I'm on Windows
>
> Thanks

Use something like this... it works great:

def get_process_info()
  procs = WIN32OLE.connect("winmgmts:\\\\.")
  procs.InstancesOf("win32_process").each do |p|
    puts p.name.to_s.downcase
  end
end
ReggW (Guest)
on 2006-06-11 17:36
Brad wrote:
> ReggW wrote:
>> How do you get a list of running Processes using Ruby?
>>
>> P.S. I'm on Windows
>>
>> Thanks
>
> Use something like this... it works great:
>
> def get_process_info()
>   procs = WIN32OLE.connect("winmgmts:\\\\.")
>   procs.InstancesOf("win32_process").each do |p|
>     puts p.name.to_s.downcase
>   end
> end

Thanks Brad...this is what I'm looking for, and it's extremely powerful!

You can replace "win32_process" with anything from the following list:
http://msdn.microsoft.com/library/default.asp?url=...
Daniel B. (Guest)
on 2006-06-11 17:48
(Received via mailing list)
Ben N. wrote:
>>>>>
>
> I don't know what you're trying to do, but here's some hackjob code to do it
> using Win32API. The basic method is to create a Toolhelp32 snapshot and then
> enumerate the processes using Process32First and Process32Next.

What I'm trying to do?  For MS Windows, sys-proctable is a wrapper
around the Win32_Process COM object via WMI.  It contains quite a bit
more information than a PROCESSENTRY32 struct.  The downside is that it
requires that your WMI service be running.

Regards,

Dan
Brad (Guest)
on 2006-06-11 20:14
ReggW wrote:
> Brad wrote:
>> ReggW wrote:
>>> How do you get a list of running Processes using Ruby?
>>>
>>> P.S. I'm on Windows
>>>
>>> Thanks
>>
>> Use something like this... it works great:
>>
>> def get_process_info()
>>   procs = WIN32OLE.connect("winmgmts:\\\\.")
>>   procs.InstancesOf("win32_process").each do |p|
>>     puts p.name.to_s.downcase
>>   end
>> end
>
> Thanks Brad...this is what I'm looking for, and it's extremely powerful!

Sure, no problem... also, you can list more than the process name. I
like to show the PID and the executablepath, etc. Here are other process
items you might like to examine:

class Win32_Process : CIM_Process
{
  string Caption;
  string CommandLine;
  string CreationClassName;
  datetime CreationDate;
  string CSCreationClassName;
  string CSName;
  string Description;
  string ExecutablePath;
  uint16 ExecutionState;
  string Handle;
  uint32 HandleCount;
  datetime InstallDate;
  uint64 KernelModeTime;
  uint32 MaximumWorkingSetSize;
  uint32 MinimumWorkingSetSize;
  string Name;
  string OSCreationClassName;
  string OSName;
  uint64 OtherOperationCount;
  uint64 OtherTransferCount;
  uint32 PageFaults;
  uint32 PageFileUsage;
  uint32 ParentProcessId;
  uint32 PeakPageFileUsage;
  uint64 PeakVirtualSize;
  uint32 PeakWorkingSetSize;
  uint32 Priority;
  uint64 PrivatePageCount;
  uint32 ProcessId;
  uint32 QuotaNonPagedPoolUsage;
  uint32 QuotaPagedPoolUsage;
  uint32 QuotaPeakNonPagedPoolUsage;
  uint32 QuotaPeakPagedPoolUsage;
  uint64 ReadOperationCount;
  uint64 ReadTransferCount;
  uint32 SessionId;
  string Status;
  datetime TerminationDate;
  uint32 ThreadCount;
  uint64 UserModeTime;
  uint64 VirtualSize;
  string WindowsVersion;
  uint64 WorkingSetSize;
  uint64 WriteOperationCount;
  uint64 WriteTransferCount;
};
This topic is locked and can not be replied to.