Module: ProcessObserver::Windows

Defined in:
lib/process_observer/windows.rb

Overview

Module with methods to interact with Windows.

Constant Summary collapse

EXE =

Task list executable.

"tasklist"

Class Method Summary collapse

Class Method Details

.call(options = {}) ⇒ String, Array<Process>

Call task list executable with provided options.

Parameters:

  • options (Hash) (defaults to: {})

    hash with call options.

Options Hash (options):

  • svc (Boolean) — default: false

    return services for each process.

  • apps (Boolean) — default: false

    return store processes.

  • v (Boolean) — default: false

    return extended info.

  • m (true, String, nil) — default: nil

    return tasks using given module or all modules if true.

  • fi (String, nil) — default: nil

    filter.

  • fo (:csv, :table, :list) — default: :csv

    format of output. if :csv is chosen output will be parsed with CSV library and returned as array of Process, otherwise whole string will be returned.

Returns:

  • (String, Array<Process>)

    call output

Raises:



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/process_observer/windows.rb', line 53

def self.call(options = {})
  raise EncodingError, "Please use `chcp 65001` to switch to UTF-8 first" if `chcp`.slice(/\d+/).to_i != 65001

  call_params = {}
  call_params[:svc]  = !!options[:svc]
  call_params[:apps] = !!options[:apps]
  call_params[:v]    = !!options[:v]
  case 
    when options[:m].nil?    then call_params[:m] = nil
    when options[:m] == true then call_params[:m] = true
    else call_params[:m] = options[:m].to_s
  end
  call_params[:fi]   = options[:fi].to_s unless options[:fi].nil?

  call_params[:fo]   = options[:fo] || :csv
  raise ArgumentError, "Unknown format option #{call_params[:fo]}", caller unless [:csv, :table, :list].include?(call_params[:fo])

  Log.debug "Call parameters: #{call_params}"
  command = call_params.empty? ? "#{EXE}" : "#{EXE} #{to_arg(call_params)}"
  Log.debug "Executing: #{command}"
  re = `#{command}`.chomp

  if call_params[:fo] == :csv
    csv = CSV.parse(re)
    enum = csv.to_a.drop(1) # Skip header
    case
      when call_params[:v] && call_params[:apps]
        # Extended info fow apps
        enum.map do |data|
          WindowsProcess.new(
            image_name: data[0],
            pid: data[1],
            session_name: data[2],
            session: data[3],
            mem_usage: data[4],
            status: data[5],
            user_name: data[6],
            cpu_time: data[7],
            window_title: data[8],
            package_name: data[9]
          )
        end
      when call_params[:v]
        # Extended info
        enum.map do |data|
          WindowsProcess.new(
            image_name: data[0],
            pid: data[1],
            session_name: data[2],
            session: data[3],
            mem_usage: data[4],
            status: data[5],
            user_name: data[6],
            cpu_time: data[7],
            window_title: data[8]
          )
        end
      when call_params[:apps]
        # Apps
        enum.map do |data|
          WindowsProcess.new(
            image_name: data[0],
            pid: data[1],
            mem_usage: data[2],
            package_name: data[3]
          )
        end
      when call_params[:m]
        # Modules
        enum.map do |data|
          WindowsProcess.new(
            image_name: data[0],
            pid: data[1],
            modules: data[2]
          )
        end
      when call_params[:svc]
        # Services
        enum.map do |data|
          WindowsProcess.new(
            image_name: data[0],
            pid: data[1],
            services: data[2]
          )
        end
      else
        # Regular mode
        enum.map do |data|
          WindowsProcess.new(
            image_name: data[0],
            pid: data[1],
            session_name: data[2],
            session: data[3],
            mem_usage: data[4]
          )
        end
    end
  else
    re.strip
  end
end

.to_arg(hash) ⇒ String

Method to turn hash with call parameters into call string argument.

@note: this method currently raises error when meet string with double quote.

Parameters:

  • hash (Hash)

    not empty hash.

Returns:

  • (String)

Raises:

  • (ArgumentError)


21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/process_observer/windows.rb', line 21

def self.to_arg(hash)
  raise ArgumentError, "Empty hash", caller if hash.empty?

  hash.map do |key, value|
    case value
      when TrueClass, FalseClass, NilClass # Boolean or nil
        value ? "/#{key}" : ""
      when String
        raise Exceptions::SpecialCharacterError, "Please don't use double quotes in string", caller if value.include?('"')
        "/#{key} \"#{value}\""
      else
        "/#{key} #{value}"
    end
  end
  .join(" ").strip.gsub(/\s+/, " ")
end