win32-process 0.5.3 → 0.5.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGES +8 -0
- data/lib/win32/process.rb +31 -21
- data/test/tc_process.rb +6 -4
- data/win32-process.gemspec +2 -2
- metadata +51 -45
- data/test/tc_process.rb~ +0 -134
data/CHANGES
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
== 0.5.4 - 23-Nov-2007
|
2
|
+
* Changed ProcessError to Process::Error.
|
3
|
+
* Now requires windows-pr 0.7.3 or later because of some reorganization in
|
4
|
+
that library with regards to thread functions.
|
5
|
+
* Better cleanup of HANDLE's in a couple methods when failure occurs.
|
6
|
+
* Added an additional require/include necessitated by a change in the method
|
7
|
+
organization in the windows-pr library.
|
8
|
+
|
1
9
|
== 0.5.3 - 29-Jul-2007
|
2
10
|
* Added a Rakefile with tasks for installation and testing.
|
3
11
|
* Removed the install.rb file (now handled by the Rakefile).
|
data/lib/win32/process.rb
CHANGED
@@ -1,17 +1,19 @@
|
|
1
1
|
require 'windows/error'
|
2
2
|
require 'windows/process'
|
3
|
+
require 'windows/thread'
|
3
4
|
require 'windows/synchronize'
|
4
5
|
require 'windows/handle'
|
5
6
|
require 'windows/library'
|
6
7
|
require 'windows/console'
|
7
8
|
require 'windows/window'
|
8
9
|
|
9
|
-
class ProcessError < RuntimeError; end
|
10
|
-
|
11
10
|
module Process
|
12
|
-
|
11
|
+
class Error < RuntimeError; end
|
12
|
+
|
13
|
+
WIN32_PROCESS_VERSION = '0.5.4'
|
13
14
|
|
14
15
|
include Windows::Process
|
16
|
+
include Windows::Thread
|
15
17
|
include Windows::Error
|
16
18
|
include Windows::Library
|
17
19
|
include Windows::Console
|
@@ -20,6 +22,7 @@ module Process
|
|
20
22
|
include Windows::Window
|
21
23
|
extend Windows::Error
|
22
24
|
extend Windows::Process
|
25
|
+
extend Windows::Thread
|
23
26
|
extend Windows::Synchronize
|
24
27
|
extend Windows::Handle
|
25
28
|
extend Windows::Library
|
@@ -46,14 +49,16 @@ module Process
|
|
46
49
|
handle = OpenProcess(PROCESS_ALL_ACCESS, 0, pid)
|
47
50
|
|
48
51
|
if handle == INVALID_HANDLE_VALUE
|
49
|
-
raise
|
52
|
+
raise Error, get_last_error
|
50
53
|
end
|
51
54
|
|
52
55
|
# TODO: update the $? global variable (if/when possible)
|
53
56
|
status = WaitForSingleObject(handle, INFINITE)
|
54
57
|
|
55
58
|
unless GetExitCodeProcess(handle, exit_code)
|
56
|
-
|
59
|
+
error = get_last_error
|
60
|
+
CloseHandle(handle)
|
61
|
+
raise Error, error
|
57
62
|
end
|
58
63
|
|
59
64
|
CloseHandle(handle)
|
@@ -76,14 +81,16 @@ module Process
|
|
76
81
|
handle = OpenProcess(PROCESS_ALL_ACCESS, 0, pid)
|
77
82
|
|
78
83
|
if handle == INVALID_HANDLE_VALUE
|
79
|
-
raise
|
84
|
+
raise Error, get_last_error
|
80
85
|
end
|
81
86
|
|
82
87
|
# TODO: update the $? global variable (if/when possible)
|
83
88
|
status = WaitForSingleObject(handle, INFINITE)
|
84
89
|
|
85
90
|
unless GetExitCodeProcess(handle, exit_code)
|
86
|
-
|
91
|
+
error = get_last_error
|
92
|
+
CloseHandle(handle)
|
93
|
+
raise Error, errorast_error
|
87
94
|
end
|
88
95
|
|
89
96
|
CloseHandle(handle)
|
@@ -124,7 +131,7 @@ module Process
|
|
124
131
|
when 0..9
|
125
132
|
# Do nothing
|
126
133
|
else
|
127
|
-
raise
|
134
|
+
raise Error, "Invalid signal '#{signal}'"
|
128
135
|
end
|
129
136
|
|
130
137
|
killed_pids = []
|
@@ -153,7 +160,7 @@ module Process
|
|
153
160
|
if GetLastError() == ERROR_ACCESS_DENIED
|
154
161
|
killed_pids.push(pid)
|
155
162
|
else
|
156
|
-
raise
|
163
|
+
raise Error, get_last_error
|
157
164
|
end
|
158
165
|
end
|
159
166
|
when 2
|
@@ -170,7 +177,7 @@ module Process
|
|
170
177
|
killed_pids.push(pid)
|
171
178
|
@child_pids.delete(pid)
|
172
179
|
else
|
173
|
-
raise
|
180
|
+
raise Error, get_last_error
|
174
181
|
end
|
175
182
|
else
|
176
183
|
if handle != 0
|
@@ -195,10 +202,10 @@ module Process
|
|
195
202
|
@child_pids.delete(pid)
|
196
203
|
else
|
197
204
|
CloseHandle(handle)
|
198
|
-
raise
|
205
|
+
raise Error, get_last_error
|
199
206
|
end
|
200
207
|
else
|
201
|
-
raise
|
208
|
+
raise Error, get_last_error
|
202
209
|
end
|
203
210
|
@child_pids.delete(pid)
|
204
211
|
end
|
@@ -211,7 +218,7 @@ module Process
|
|
211
218
|
#
|
212
219
|
# This is a wrapper for the CreateProcess() function. It executes a process,
|
213
220
|
# returning a ProcessInfo struct. It accepts a hash as an argument.
|
214
|
-
# There are
|
221
|
+
# There are eight primary keys:
|
215
222
|
#
|
216
223
|
# * app_name (mandatory)
|
217
224
|
# * inherit (default: false)
|
@@ -287,7 +294,7 @@ module Process
|
|
287
294
|
args.each{ |key, val|
|
288
295
|
key = key.to_s.downcase
|
289
296
|
unless valid_keys.include?(key)
|
290
|
-
raise
|
297
|
+
raise Error, "invalid key '#{key}'"
|
291
298
|
end
|
292
299
|
|
293
300
|
# Convert true to 1 and nil/false to 0.
|
@@ -308,7 +315,7 @@ module Process
|
|
308
315
|
hash['startup_info'].each{ |key, val|
|
309
316
|
key = key.to_s.downcase
|
310
317
|
unless valid_si_keys.include?(key)
|
311
|
-
raise
|
318
|
+
raise Error, "invalid startup_info key '#{key}'"
|
312
319
|
end
|
313
320
|
si_hash[key] = val
|
314
321
|
}
|
@@ -316,7 +323,7 @@ module Process
|
|
316
323
|
|
317
324
|
# The +app_name+ key is mandatory
|
318
325
|
unless hash['app_name']
|
319
|
-
raise
|
326
|
+
raise Error, 'app_name must be specified'
|
320
327
|
end
|
321
328
|
|
322
329
|
# The environment string should be passed as a string of ';' separated
|
@@ -357,7 +364,7 @@ module Process
|
|
357
364
|
end
|
358
365
|
|
359
366
|
if handle == INVALID_HANDLE_VALUE
|
360
|
-
raise
|
367
|
+
raise Error, get_last_error
|
361
368
|
end
|
362
369
|
|
363
370
|
si_hash[io] = handle
|
@@ -397,7 +404,7 @@ module Process
|
|
397
404
|
)
|
398
405
|
|
399
406
|
unless bool
|
400
|
-
raise
|
407
|
+
raise Error, "CreateProcess() failed: ", get_last_error
|
401
408
|
end
|
402
409
|
|
403
410
|
ProcessInfo.new(
|
@@ -430,7 +437,7 @@ module Process
|
|
430
437
|
|
431
438
|
if handles[i] == INVALID_HANDLE_VALUE
|
432
439
|
err = "unable to get HANDLE on process associated with pid #{pid}"
|
433
|
-
raise
|
440
|
+
raise Error, err
|
434
441
|
end
|
435
442
|
|
436
443
|
unless defined? GetProcessId
|
@@ -485,7 +492,7 @@ module Process
|
|
485
492
|
|
486
493
|
if handles[i] == INVALID_HANDLE_VALUE
|
487
494
|
err = "unable to get HANDLE on process associated with pid #{pid}"
|
488
|
-
raise
|
495
|
+
raise Error, err
|
489
496
|
end
|
490
497
|
|
491
498
|
unless defined? GetProcessId
|
@@ -565,7 +572,7 @@ module Process
|
|
565
572
|
rv = CreateProcess(0, cmd, 0, 0, 1, 0, 0, 0, startinfo, procinfo)
|
566
573
|
|
567
574
|
if rv == 0
|
568
|
-
raise
|
575
|
+
raise Error, get_last_error
|
569
576
|
end
|
570
577
|
|
571
578
|
pid = procinfo[8,4].unpack('L').first
|
@@ -577,6 +584,9 @@ module Process
|
|
577
584
|
module_function :kill, :wait, :wait2, :waitpid, :waitpid2, :create, :fork
|
578
585
|
end
|
579
586
|
|
587
|
+
# For backwards compatibility. Deprecated.
|
588
|
+
ProcessError = Process::Error
|
589
|
+
|
580
590
|
# Create a global fork method
|
581
591
|
module Kernel
|
582
592
|
def fork(&block)
|
data/test/tc_process.rb
CHANGED
@@ -43,7 +43,7 @@ class TC_Win32Process < Test::Unit::TestCase
|
|
43
43
|
end
|
44
44
|
|
45
45
|
def test_version
|
46
|
-
assert_equal('0.5.
|
46
|
+
assert_equal('0.5.4', Process::WIN32_PROCESS_VERSION)
|
47
47
|
end
|
48
48
|
|
49
49
|
def test_kill
|
@@ -52,8 +52,8 @@ class TC_Win32Process < Test::Unit::TestCase
|
|
52
52
|
|
53
53
|
def test_kill_expected_errors
|
54
54
|
assert_raises(ArgumentError){ Process.kill }
|
55
|
-
assert_raises(
|
56
|
-
assert_raises(
|
55
|
+
assert_raises(Process::Error){ Process.kill('SIGBOGUS') }
|
56
|
+
assert_raises(Process::Error){ Process.kill(0,9999999) }
|
57
57
|
end
|
58
58
|
|
59
59
|
def test_kill_signal_0
|
@@ -92,7 +92,9 @@ class TC_Win32Process < Test::Unit::TestCase
|
|
92
92
|
|
93
93
|
def test_create_expected_errors
|
94
94
|
assert_raises(TypeError){ Process.create("bogusapp.exe") }
|
95
|
-
assert_raises(
|
95
|
+
assert_raises(Process::Error){
|
96
|
+
Process.create(:app_name => "bogusapp.exe")
|
97
|
+
}
|
96
98
|
end
|
97
99
|
|
98
100
|
def test_wait
|
data/win32-process.gemspec
CHANGED
@@ -2,7 +2,7 @@ require "rubygems"
|
|
2
2
|
|
3
3
|
spec = Gem::Specification.new do |gem|
|
4
4
|
gem.name = "win32-process"
|
5
|
-
gem.version = "0.5.
|
5
|
+
gem.version = "0.5.4"
|
6
6
|
gem.author = "Daniel J. Berger"
|
7
7
|
gem.email = "djberg96@gmail.com"
|
8
8
|
gem.homepage = "http://www.rubyforge.org/projects/win32utils"
|
@@ -15,7 +15,7 @@ spec = Gem::Specification.new do |gem|
|
|
15
15
|
gem.files.reject! { |fn| fn.include? "CVS" }
|
16
16
|
gem.require_path = "lib"
|
17
17
|
gem.extra_rdoc_files = ["README", "CHANGES", "MANIFEST"]
|
18
|
-
gem.add_dependency("windows-pr", ">= 0.
|
18
|
+
gem.add_dependency("windows-pr", ">= 0.7.3")
|
19
19
|
end
|
20
20
|
|
21
21
|
if $0 == __FILE__
|
metadata
CHANGED
@@ -1,38 +1,40 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
|
-
rubygems_version: 0.9.4
|
3
|
-
specification_version: 1
|
4
2
|
name: win32-process
|
5
3
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.5.
|
7
|
-
date: 2007-07-29 00:00:00 -06:00
|
8
|
-
summary: Adds fork, wait, wait2, waitpid, waitpid2 and a special kill method
|
9
|
-
require_paths:
|
10
|
-
- lib
|
11
|
-
email: djberg96@gmail.com
|
12
|
-
homepage: http://www.rubyforge.org/projects/win32utils
|
13
|
-
rubyforge_project:
|
14
|
-
description: Adds fork, wait, wait2, waitpid, waitpid2 and a special kill method
|
15
|
-
autorequire:
|
16
|
-
default_executable:
|
17
|
-
bindir: bin
|
18
|
-
has_rdoc: true
|
19
|
-
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
-
requirements:
|
21
|
-
- - ">"
|
22
|
-
- !ruby/object:Gem::Version
|
23
|
-
version: 0.0.0
|
24
|
-
version:
|
4
|
+
version: 0.5.4
|
25
5
|
platform: ruby
|
26
|
-
signing_key:
|
27
|
-
cert_chain:
|
28
|
-
post_install_message:
|
29
6
|
authors:
|
30
7
|
- Daniel J. Berger
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2007-11-23 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: windows-pr
|
17
|
+
version_requirement:
|
18
|
+
version_requirements: !ruby/object:Gem::Requirement
|
19
|
+
requirements:
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 0.7.3
|
23
|
+
version:
|
24
|
+
description: Adds fork, wait, wait2, waitpid, waitpid2 and a special kill method
|
25
|
+
email: djberg96@gmail.com
|
26
|
+
executables: []
|
27
|
+
|
28
|
+
extensions: []
|
29
|
+
|
30
|
+
extra_rdoc_files:
|
31
|
+
- README
|
32
|
+
- CHANGES
|
33
|
+
- MANIFEST
|
31
34
|
files:
|
32
35
|
- lib/win32/process.rb
|
33
36
|
- test/CVS
|
34
37
|
- test/tc_process.rb
|
35
|
-
- test/tc_process.rb~
|
36
38
|
- CHANGES
|
37
39
|
- CVS
|
38
40
|
- examples
|
@@ -42,27 +44,31 @@ files:
|
|
42
44
|
- README
|
43
45
|
- test
|
44
46
|
- win32-process.gemspec
|
45
|
-
|
46
|
-
|
47
|
+
has_rdoc: true
|
48
|
+
homepage: http://www.rubyforge.org/projects/win32utils
|
49
|
+
post_install_message:
|
47
50
|
rdoc_options: []
|
48
51
|
|
49
|
-
|
50
|
-
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
52
|
+
require_paths:
|
53
|
+
- lib
|
54
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: "0"
|
59
|
+
version:
|
60
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
61
|
+
requirements:
|
62
|
+
- - ">="
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: "0"
|
65
|
+
version:
|
57
66
|
requirements: []
|
58
67
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
- !ruby/object:Gem::Version
|
67
|
-
version: 0.5.2
|
68
|
-
version:
|
68
|
+
rubyforge_project:
|
69
|
+
rubygems_version: 0.9.5
|
70
|
+
signing_key:
|
71
|
+
specification_version: 2
|
72
|
+
summary: Adds fork, wait, wait2, waitpid, waitpid2 and a special kill method
|
73
|
+
test_files:
|
74
|
+
- test/tc_process.rb
|
data/test/tc_process.rb~
DELETED
@@ -1,134 +0,0 @@
|
|
1
|
-
###############################################################################
|
2
|
-
# tc_process.rb
|
3
|
-
#
|
4
|
-
# Test suite for the win32-process package. This test suite will start
|
5
|
-
# at least two instances of Notepad on your system, which will then
|
6
|
-
# be killed. Requires the sys-proctable package.
|
7
|
-
#
|
8
|
-
# I haven't added a lot of test cases for fork/wait because it's difficult
|
9
|
-
# to run such tests without causing havoc with TestUnit itself. Ideas
|
10
|
-
# welcome.
|
11
|
-
###############################################################################
|
12
|
-
Dir.chdir('..') if File.basename(Dir.pwd) == 'test'
|
13
|
-
$LOAD_PATH.unshift Dir.pwd
|
14
|
-
$LOAD_PATH.unshift Dir.pwd + '/lib'
|
15
|
-
Dir.chdir('test') rescue nil
|
16
|
-
|
17
|
-
require 'test/unit'
|
18
|
-
require 'win32/process'
|
19
|
-
|
20
|
-
begin
|
21
|
-
require 'sys/proctable'
|
22
|
-
rescue LoadError => e
|
23
|
-
site = 'http://www.rubyforge.org/projects/sysutils'
|
24
|
-
STDERR.puts "Stopping!"
|
25
|
-
STDERR.puts "The sys/proctable module is required to run this test suite."
|
26
|
-
STDERR.puts "You can find it at #{site} or the RAA"
|
27
|
-
exit!
|
28
|
-
end
|
29
|
-
|
30
|
-
include Sys
|
31
|
-
|
32
|
-
IO.popen("notepad")
|
33
|
-
IO.popen("notepad")
|
34
|
-
sleep 1
|
35
|
-
|
36
|
-
$pids = []
|
37
|
-
ProcTable.ps{ |s|
|
38
|
-
next unless s.comm =~ /notepad/i
|
39
|
-
$pids.push(s.pid)
|
40
|
-
}
|
41
|
-
|
42
|
-
class TC_Win32Process < Test::Unit::TestCase
|
43
|
-
def setup
|
44
|
-
@pids = $pids
|
45
|
-
@pid = nil
|
46
|
-
end
|
47
|
-
|
48
|
-
def test_version
|
49
|
-
assert_equal('0.5.3', Process::WIN32_PROCESS_VERSION)
|
50
|
-
end
|
51
|
-
|
52
|
-
def test_kill
|
53
|
-
assert_respond_to(Process, :kill)
|
54
|
-
end
|
55
|
-
|
56
|
-
def test_kill_expected_errors
|
57
|
-
assert_raises(ArgumentError){ Process.kill }
|
58
|
-
assert_raises(ProcessError){ Process.kill('SIGBOGUS') }
|
59
|
-
assert_raises(ProcessError){ Process.kill(0,9999999) }
|
60
|
-
end
|
61
|
-
|
62
|
-
def test_kill_signal_0
|
63
|
-
pid = @pids.first
|
64
|
-
assert_nothing_raised{ Process.kill(0, pid) }
|
65
|
-
end
|
66
|
-
|
67
|
-
def test_kill_signal_1
|
68
|
-
pid = @pids.shift
|
69
|
-
assert_nothing_raised{ Process.kill(1, pid) }
|
70
|
-
end
|
71
|
-
|
72
|
-
def test_kill_signal_9
|
73
|
-
pid = @pids.pop
|
74
|
-
msg = "Could not find pid #{pid}"
|
75
|
-
assert_nothing_raised(msg){ Process.kill(9,pid) }
|
76
|
-
end
|
77
|
-
|
78
|
-
def test_fork
|
79
|
-
assert_respond_to(Process, :fork)
|
80
|
-
end
|
81
|
-
|
82
|
-
def test_create
|
83
|
-
assert_respond_to(Process, :create)
|
84
|
-
assert_nothing_raised{
|
85
|
-
@pid = Process.create(
|
86
|
-
:app_name => "notepad.exe",
|
87
|
-
:creation_flags => Process::DETACHED_PROCESS,
|
88
|
-
:process_inherit => false,
|
89
|
-
:thread_inherit => true,
|
90
|
-
:cwd => "C:\\"
|
91
|
-
).process_id
|
92
|
-
}
|
93
|
-
assert_nothing_raised{ Process.kill(1, @pid) }
|
94
|
-
end
|
95
|
-
|
96
|
-
def test_create_expected_errors
|
97
|
-
assert_raises(TypeError){ Process.create("bogusapp.exe") }
|
98
|
-
assert_raises(ProcessError){ Process.create(:app_name => "bogusapp.exe") }
|
99
|
-
end
|
100
|
-
|
101
|
-
def test_wait
|
102
|
-
assert_respond_to(Process, :wait)
|
103
|
-
end
|
104
|
-
|
105
|
-
def test_wait2
|
106
|
-
assert_respond_to(Process, :wait2)
|
107
|
-
end
|
108
|
-
|
109
|
-
def test_waitpid
|
110
|
-
assert_respond_to(Process, :waitpid)
|
111
|
-
end
|
112
|
-
|
113
|
-
def test_waitpid2
|
114
|
-
assert_respond_to(Process, :waitpid2)
|
115
|
-
end
|
116
|
-
|
117
|
-
def test_creation_constants
|
118
|
-
assert_not_nil(Process::CREATE_DEFAULT_ERROR_MODE)
|
119
|
-
assert_not_nil(Process::CREATE_NEW_CONSOLE)
|
120
|
-
assert_not_nil(Process::CREATE_NEW_PROCESS_GROUP)
|
121
|
-
assert_not_nil(Process::CREATE_NO_WINDOW)
|
122
|
-
assert_not_nil(Process::CREATE_SEPARATE_WOW_VDM)
|
123
|
-
assert_not_nil(Process::CREATE_SHARED_WOW_VDM)
|
124
|
-
assert_not_nil(Process::CREATE_SUSPENDED)
|
125
|
-
assert_not_nil(Process::CREATE_UNICODE_ENVIRONMENT)
|
126
|
-
assert_not_nil(Process::DEBUG_ONLY_THIS_PROCESS)
|
127
|
-
assert_not_nil(Process::DEBUG_PROCESS)
|
128
|
-
assert_not_nil(Process::DETACHED_PROCESS)
|
129
|
-
end
|
130
|
-
|
131
|
-
def teardown
|
132
|
-
@pids = []
|
133
|
-
end
|
134
|
-
end
|