【Ruby】プロセス名に基づいてプロセスIDを取得
ファイル名 processid.rb
サンプルコード:
include Sys
require 'win32ole'
require 'socket'
require 'date'
# The Sys module serves as a namespace only
module Sys
# The ProcTable class encapsulates process table information
class ProcTable
# There is no constructor
private_class_method :new
# Error typically raised if one of the Sys::ProcTable methods fails
class Error < StandardError; end
# The version of the sys-proctable library
VERSION = '0.9.0'
# The comm field corresponds to the 'name' field. The 'cmdline' field
# is the CommandLine attribute on Windows XP or later, or the
# 'executable_path' field on Windows 2000 or earlier.
#
@fields = %w/
caption
cmdline
comm
creation_class_name
creation_date
cs_creation_class_name
cs_name
description
executable_path
execution_state
handle
handle_count
install_date
kernel_mode_time
maximum_working_set_size
minimum_working_set_size
name
os_creation_class_name
os_name
other_operation_count
other_transfer_count
page_faults
page_file_usage
ppid
peak_page_file_usage
peak_virtual_size
peak_working_set_size
priority
private_page_count
pid
quota_non_paged_pool_usage
quota_paged_pool_usage
quota_peak_non_paged_pool_usage
quota_peak_paged_pool_usage
read_operation_count
read_transfer_count
session_id
status
termination_date
thread_count
user_mode_time
virtual_size
windows_version
working_set_size
write_operation_count
write_transfer_count
/
ProcTableStruct = Struct.new("ProcTableStruct", *@fields)
# call-seq:
# ProcTable.fields
#
# Returns an array of fields that each ProcTableStruct will contain. This
# may be useful if you want to know in advance what fields are available
# without having to perform at least one read of the /proc table.
#
def self.fields
@fields
end
# call-seq:
# ProcTable.ps(pid=nil)
# ProcTable.ps(pid=nil){ |ps| ... }
#
# In block form, yields a ProcTableStruct for each process entry that you
# have rights to. This method returns an array of ProcTableStruct's in
# non-block form.
#
# If a +pid+ is provided, then only a single ProcTableStruct is yielded or
# returned, or nil if no process information is found for that +pid+.
#
def self.ps(pid=nil, host=Socket.gethostname)
if pid
raise TypeError unless pid.kind_of?(Fixnum)
end
array = block_given? ? nil : []
struct = nil
begin
wmi = WIN32OLE.connect("winmgmts://#{host}/root/cimv2")
rescue WIN32OLERuntimeError => e
raise Error, e # Re-raise as ProcTable::Error
else
wmi.InstancesOf("Win32_Process").each{ |wproc|
if pid
next unless wproc.ProcessId == pid
end
# Some fields are added later, and so are nil initially
struct = ProcTableStruct.new(
wproc.Caption,
nil, # Added later, based on OS version
wproc.Name,
wproc.CreationClassName,
self.parse_ms_date(wproc.CreationDate),
wproc.CSCreationClassName,
wproc.CSName,
wproc.Description,
wproc.ExecutablePath,
wproc.ExecutionState,
wproc.Handle,
wproc.HandleCount,
self.parse_ms_date(wproc.InstallDate),
self.convert(wproc.KernelModeTime),
wproc.MaximumWorkingSetSize,
wproc.MinimumWorkingSetSize,
wproc.Name,
wproc.OSCreationClassName,
wproc.OSName,
self.convert(wproc.OtherOperationCount),
self.convert(wproc.OtherTransferCount),
wproc.PageFaults,
wproc.PageFileUsage,
wproc.ParentProcessId,
self.convert(wproc.PeakPageFileUsage),
self.convert(wproc.PeakVirtualSize),
self.convert(wproc.PeakWorkingSetSize),
wproc.Priority,
self.convert(wproc.PrivatePageCount),
wproc.ProcessId,
wproc.QuotaNonPagedPoolUsage,
wproc.QuotaPagedPoolUsage,
wproc.QuotaPeakNonPagedPoolUsage,
wproc.QuotaPeakPagedPoolUsage,
self.convert(wproc.ReadOperationCount),
self.convert(wproc.ReadTransferCount),
wproc.SessionId,
wproc.Status,
self.parse_ms_date(wproc.TerminationDate),
wproc.ThreadCount,
self.convert(wproc.UserModeTime),
self.convert(wproc.VirtualSize),
wproc.WindowsVersion,
self.convert(wproc.WorkingSetSize),
self.convert(wproc.WriteOperationCount),
self.convert(wproc.WriteTransferCount)
)
###############################################################
# On Windows XP or later, set the cmdline to the CommandLine
# attribute. Otherwise, set it to the ExecutablePath
# attribute.
###############################################################
if wproc.WindowsVersion.to_f < 5.1
struct.cmdline = wproc.ExecutablePath
else
struct.cmdline = wproc.CommandLine
end
struct.freeze # This is read-only data
if block_given?
yield struct
else
array << struct
end
}
end
pid ? struct : array
end
private
#######################################################################
# Converts a string in the format '20040703074625.015625-360' into a
# Ruby Time object.
#######################################################################
def self.parse_ms_date(str)
return if str.nil?
return Date.parse(str.split('.').first)
end
#####################################################################
# There is a bug in win32ole where uint64 types are returned as a
# String instead of a Fixnum. This method deals with that for now.
#####################################################################
def self.convert(str)
return nil if str.nil? # Return nil, not 0
return str.to_i
end
end
end
ProcTable.ps{ |p|
puts p.pid.to_s if p.comm=='explorer.exe'
}