class Win32::Pdh::Counter

Class representing an individual counter.

This won't usually be created directly, but built using Query#add_counter.

Attributes

counter_name[RW]
default_scale[RW]
explain_text[RW]
full_path[RW]
instance_index[RW]
instance_name[RW]
machine_name[RW]
object_name[RW]
parent_instance[RW]
scale[RW]
status[RW]
type[RW]
version[RW]

Public Class Methods

new(query:, path:) click to toggle source

Initializes the counter from a query and a path. This usually won't be called directly, but generated from Query#add_counter

# File lib/win32/pdh/counter.rb, line 66
def initialize(query:, path:)
  path = (path + "\0").encode('UTF-16LE')
  handle_pointer = FFI::MemoryPointer.new(:pointer)
  status = PdhFFI.PdhAddCounterW(
    query,
    path,
    FFI::Pointer::NULL,
    handle_pointer,
  )
  Pdh.check_status status
  @handle = handle_pointer.read_pointer

  # Make sure we don't leak when we throw an exception
  begin
    load_info
  rescue
    remove
    raise
  end
end

Public Instance Methods

close()
Alias for: remove
get(format) click to toggle source

Get the PDH_FMT_COUNTERVALUE_VALUE given the format, checking status and raising an exception if necessary.

Usually, you won't use this directly; you'd use get_double, get_long, or get_large to get the formatted value without any hassle.

Will raise a PdhError if the value is bad (if you've only run Query#collect_query_data once, but this counter requires a history to calculate a rate, this will raise an exception. Be careful, and probably wrap all calls to this in an exception block that takes into account the possibility of a counter failing to get a value)

# File lib/win32/pdh/counter.rb, line 151
def get(format)
  value = PDH_FMT_COUNTERVALUE.new
  status = PdhFFI.PdhGetFormattedCounterValue(
    @handle,
    format,
    FFI::Pointer::NULL,
    value,
  )
  Pdh.check_status status
  Pdh.check_status value[:CStatus]
  value[:value]
end
get_double() click to toggle source

Get value as a double.

This uses get, so read the notes in there about exception raising.

# File lib/win32/pdh/counter.rb, line 168
def get_double
  get(Constants::PDH_FMT_DOUBLE)[:doubleValue]
end
get_large() click to toggle source

Get value as a 64-bit integer.

This uses get, so read the notes in there about exception raising.

# File lib/win32/pdh/counter.rb, line 176
def get_large
  get(Constants::PDH_FMT_LARGE)[:largeValue]
end
get_long() click to toggle source

Get value as a 32-bit integer

This uses get, so read the notes in there about exception raising.

# File lib/win32/pdh/counter.rb, line 184
def get_long
  get(Constants::PDH_FMT_LONG)[:longValue]
end
remove() click to toggle source

Remove the counter from its Query.

This isn't necessary as a part of general cleanup, as closing a Query will also clean up all counters. This is necessary if you are doing long-term management that may need counters added and removed while running. So if you're using a Query as a one-off and it is being closed after use, don't bother with this. If you are keeping a single query open long-term, make sure you use this when necessary, otherwise you will leak memory.

# File lib/win32/pdh/counter.rb, line 97
def remove
  # Only allow removing once
  unless @handle.nil?
    status = PdhFFI.PdhRemoveCounter(@handle) unless @handle.nil?
    Pdh.check_status status
    @handle = nil
  end
end
Also aliased as: close

Private Instance Methods

load_info() click to toggle source
# File lib/win32/pdh/counter.rb, line 108
def load_info
  buffersize = FFI::MemoryPointer.new(:uint)
  buffersize.write_uint(0)
  buffer = FFI::Pointer::NULL
  status = nil
  while status.nil? || status == Constants::PDH_MORE_DATA
    buffer = FFI::Buffer.new(:uint16, buffersize.read_uint) unless status.nil?
    status = PdhFFI.PdhGetCounterInfoW(@handle, :false, buffersize, buffer)
  end
  Pdh.check_status status

  info = PDH_COUNTER_INFO.new(buffer)
  @type = info[:dwType]
  @version = info[:CVersion]
  @status = info[:CStatus]
  @scale = info[:lScale]
  @default_scale = info[:lDefaultScale]
  @full_path = Pdh.read_cwstr(info[:szFullPath]).freeze
  counter_path = info[:CounterPath]
  @machine_name = Pdh.read_cwstr(counter_path[:szMachineName]).freeze
  @object_name = Pdh.read_cwstr(counter_path[:szObjectName]).freeze
  @instance_name = Pdh.read_cwstr(counter_path[:szInstanceName]).freeze
  @parent_instance = Pdh.read_cwstr(counter_path[:szParentInstance]).freeze
  @instance_index = counter_path[:dwInstanceIndex]
  @counter_name = Pdh.read_cwstr(counter_path[:szCounterName]).freeze
  @explain_text = Pdh.read_cwstr(info[:szExplainText]).freeze
  Pdh.check_status @status
end