win32-process 0.5.4 → 0.5.5
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +7 -0
- data/lib/win32/process.rb +86 -41
- data/win32-process.gemspec +5 -4
- metadata +5 -5
data/CHANGES
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
== 0.5.5 - 12-Dec-2007
|
2
|
+
* The Process.create method now automatically closes the process and thread
|
3
|
+
handles in the ProcessInfo struct before returning, unless you explicitly
|
4
|
+
tell it not to via the 'close_handles' option.
|
5
|
+
* The Process.create method now supports creating a process as another user
|
6
|
+
via the 'with_logon', 'password' and 'domain' options.
|
7
|
+
|
1
8
|
== 0.5.4 - 23-Nov-2007
|
2
9
|
* Changed ProcessError to Process::Error.
|
3
10
|
* Now requires windows-pr 0.7.3 or later because of some reorganization in
|
data/lib/win32/process.rb
CHANGED
@@ -6,11 +6,12 @@ require 'windows/handle'
|
|
6
6
|
require 'windows/library'
|
7
7
|
require 'windows/console'
|
8
8
|
require 'windows/window'
|
9
|
+
require 'windows/unicode'
|
9
10
|
|
10
11
|
module Process
|
11
12
|
class Error < RuntimeError; end
|
12
13
|
|
13
|
-
WIN32_PROCESS_VERSION = '0.5.
|
14
|
+
WIN32_PROCESS_VERSION = '0.5.5'
|
14
15
|
|
15
16
|
include Windows::Process
|
16
17
|
include Windows::Thread
|
@@ -20,6 +21,7 @@ module Process
|
|
20
21
|
include Windows::Handle
|
21
22
|
include Windows::Synchronize
|
22
23
|
include Windows::Window
|
24
|
+
include Windows::Unicode
|
23
25
|
extend Windows::Error
|
24
26
|
extend Windows::Process
|
25
27
|
extend Windows::Thread
|
@@ -27,6 +29,7 @@ module Process
|
|
27
29
|
extend Windows::Handle
|
28
30
|
extend Windows::Library
|
29
31
|
extend Windows::Console
|
32
|
+
extend Windows::Unicode
|
30
33
|
|
31
34
|
# Used by Process.create
|
32
35
|
ProcessInfo = Struct.new("ProcessInfo",
|
@@ -216,9 +219,9 @@ module Process
|
|
216
219
|
|
217
220
|
# Process.create(key => value, ...) => ProcessInfo
|
218
221
|
#
|
219
|
-
# This is a wrapper for the CreateProcess() function.
|
220
|
-
# returning a ProcessInfo struct.
|
221
|
-
# There are
|
222
|
+
# This is a wrapper for the CreateProcess() function. It executes a process,
|
223
|
+
# returning a ProcessInfo struct. It accepts a hash as an argument.
|
224
|
+
# There are several primary keys:
|
222
225
|
#
|
223
226
|
# * app_name (mandatory)
|
224
227
|
# * inherit (default: false)
|
@@ -228,12 +231,19 @@ module Process
|
|
228
231
|
# * cwd (default: Dir.pwd)
|
229
232
|
# * startup_info (default: nil)
|
230
233
|
# * environment (default: nil)
|
234
|
+
# * close_handles (default: true)
|
235
|
+
# * with_logon (default: nil)
|
236
|
+
# * domain (default: nil)
|
237
|
+
# * password (default: nil)
|
231
238
|
#
|
232
239
|
# Of these, the 'app_name' must be specified or an error is raised.
|
240
|
+
#
|
241
|
+
# The 'domain' and 'password' options are only relevent in the context
|
242
|
+
# of 'with_logon'.
|
233
243
|
#
|
234
|
-
# The startup_info key takes a hash.
|
244
|
+
# The startup_info key takes a hash. Its keys are attributes that are
|
235
245
|
# part of the StartupInfo struct, and are generally only meaningful for
|
236
|
-
# GUI or console processes.
|
246
|
+
# GUI or console processes. See the documentation on CreateProcess()
|
237
247
|
# and the StartupInfo struct on MSDN for more information.
|
238
248
|
#
|
239
249
|
# * desktop
|
@@ -253,9 +263,9 @@ module Process
|
|
253
263
|
#
|
254
264
|
# The relevant constants for 'creation_flags', 'sw_flags' and 'startf_flags'
|
255
265
|
# are included in the Windows::Process, Windows::Console and Windows::Window
|
256
|
-
# modules.
|
257
|
-
#
|
258
|
-
# either Ruby IO objects or file descriptors (i.e. a fileno).
|
266
|
+
# modules. These come with the windows-pr library, a prerequisite of this
|
267
|
+
# library. Note that the 'stdin', 'stdout' and 'stderr' options can be
|
268
|
+
# either Ruby IO objects or file descriptors (i.e. a fileno). However,
|
259
269
|
# StringIO objects are not currently supported.
|
260
270
|
#
|
261
271
|
# The ProcessInfo struct contains the following members:
|
@@ -265,6 +275,13 @@ module Process
|
|
265
275
|
# * process_id - Process ID.
|
266
276
|
# * thread_id - Thread ID.
|
267
277
|
#
|
278
|
+
# If the 'close_handles' option is set to true (the default) then the
|
279
|
+
# process_handle and the thread_handle are automatically closed for you
|
280
|
+
# before the ProcessInfo struct is returned.
|
281
|
+
#
|
282
|
+
# If the 'with_logon' option is set, then the process runs the specified
|
283
|
+
# executable file in the security context of the specified credentials.
|
284
|
+
#
|
268
285
|
def create(args)
|
269
286
|
unless args.kind_of?(Hash)
|
270
287
|
raise TypeError, 'Expecting hash-style keyword arguments'
|
@@ -272,7 +289,8 @@ module Process
|
|
272
289
|
|
273
290
|
valid_keys = %w/
|
274
291
|
app_name inherit creation_flags cwd environment startup_info
|
275
|
-
thread_inherit process_inherit
|
292
|
+
thread_inherit process_inherit close_handles with_logon domain
|
293
|
+
password
|
276
294
|
/
|
277
295
|
|
278
296
|
valid_si_keys = %/
|
@@ -280,15 +298,11 @@ module Process
|
|
280
298
|
y_count_chars fill_attribute sw_flags stdin stdout stderr
|
281
299
|
/
|
282
300
|
|
283
|
-
# Set
|
301
|
+
# Set default values
|
284
302
|
hash = {
|
285
|
-
'
|
286
|
-
'
|
287
|
-
'thread_inherit' => 0,
|
288
|
-
'creation_flags' => 0,
|
289
|
-
'cwd' => 0
|
303
|
+
'creation_flags' => 0,
|
304
|
+
'close_handles' => true
|
290
305
|
}
|
291
|
-
env = 0
|
292
306
|
|
293
307
|
# Validate the keys, and convert symbols and case to lowercase strings.
|
294
308
|
args.each{ |key, val|
|
@@ -296,16 +310,7 @@ module Process
|
|
296
310
|
unless valid_keys.include?(key)
|
297
311
|
raise Error, "invalid key '#{key}'"
|
298
312
|
end
|
299
|
-
|
300
|
-
# Convert true to 1 and nil/false to 0.
|
301
|
-
case val
|
302
|
-
when true, false
|
303
|
-
hash[key] = val == false ? 0 : 1
|
304
|
-
when nil
|
305
|
-
hash[key] = 0 # Win32API sometimes doesn't like nil
|
306
|
-
else
|
307
|
-
hash[key] = val
|
308
|
-
end
|
313
|
+
hash[key] = val
|
309
314
|
}
|
310
315
|
|
311
316
|
si_hash = {}
|
@@ -330,7 +335,14 @@ module Process
|
|
330
335
|
# paths.
|
331
336
|
if hash['environment']
|
332
337
|
env = hash['environment'].split(File::PATH_SEPARATOR) << 0.chr
|
333
|
-
|
338
|
+
if hash['with_logon']
|
339
|
+
env = env.map{ |e| multi_to_wide(e) }
|
340
|
+
env = [env.join("\0\0")].pack('p*').unpack('L').first
|
341
|
+
else
|
342
|
+
env = [env.join("\0")].pack('p*').unpack('L').first
|
343
|
+
end
|
344
|
+
else
|
345
|
+
env = nil
|
334
346
|
end
|
335
347
|
|
336
348
|
startinfo = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
|
@@ -390,23 +402,56 @@ module Process
|
|
390
402
|
startinfo[64,4] = [si_hash['stderr']].pack('L') if si_hash['stderr']
|
391
403
|
end
|
392
404
|
|
393
|
-
|
394
|
-
|
395
|
-
hash['
|
396
|
-
|
397
|
-
|
398
|
-
hash['
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
405
|
+
if hash['with_logon']
|
406
|
+
logon = multi_to_wide(hash['with_logon'])
|
407
|
+
domain = multi_to_wide(hash['domain'])
|
408
|
+
app = multi_to_wide(hash['app_name'])
|
409
|
+
cwd = multi_to_wide(hash['cwd'])
|
410
|
+
passwd = multi_to_wide(hash['password'])
|
411
|
+
|
412
|
+
hash['creation_flags'] |= CREATE_UNICODE_ENVIRONMENT
|
413
|
+
|
414
|
+
bool = CreateProcessWithLogonW(
|
415
|
+
logon, # User
|
416
|
+
domain, # Domain
|
417
|
+
passwd, # Password
|
418
|
+
LOGON_WITH_PROFILE, # Logon flags
|
419
|
+
nil, # App name
|
420
|
+
app, # Command line
|
421
|
+
hash['creation_flags'], # Creation flags
|
422
|
+
env, # Environment
|
423
|
+
cwd, # Working directory
|
424
|
+
startinfo, # Startup Info
|
425
|
+
procinfo # Process Info
|
426
|
+
)
|
427
|
+
else
|
428
|
+
bool = CreateProcess(
|
429
|
+
nil, # App name
|
430
|
+
hash['app_name'], # Command line
|
431
|
+
process_security, # Process attributes
|
432
|
+
thread_security, # Thread attributes
|
433
|
+
hash['inherit'], # Inherit handles?
|
434
|
+
hash['creation_flags'], # Creation flags
|
435
|
+
env, # Environment
|
436
|
+
hash['cwd'], # Working directory
|
437
|
+
startinfo, # Startup Info
|
438
|
+
procinfo # Process Info
|
439
|
+
)
|
440
|
+
end
|
441
|
+
|
442
|
+
# TODO: Close stdin, stdout and stderr handles in the si_hash unless
|
443
|
+
# they're pointing to one of the standard handles already.
|
406
444
|
unless bool
|
407
445
|
raise Error, "CreateProcess() failed: ", get_last_error
|
408
446
|
end
|
409
447
|
|
448
|
+
# Automatically close the process and thread handles in the
|
449
|
+
# PROCESS_INFORMATION struct unless explicitly told not to.
|
450
|
+
if hash['close_handles']
|
451
|
+
CloseHandle(procinfo[8,4].unpack('L').first)
|
452
|
+
CloseHandle(procinfo[12,4].unpack('L').first)
|
453
|
+
end
|
454
|
+
|
410
455
|
ProcessInfo.new(
|
411
456
|
procinfo[0,4].unpack('L').first, # hProcess
|
412
457
|
procinfo[4,4].unpack('L').first, # hThread
|
data/win32-process.gemspec
CHANGED
@@ -1,21 +1,22 @@
|
|
1
1
|
require "rubygems"
|
2
2
|
|
3
3
|
spec = Gem::Specification.new do |gem|
|
4
|
+
desc = "Adds create, fork, wait, wait2, waitpid, and a special kill method"
|
4
5
|
gem.name = "win32-process"
|
5
|
-
gem.version = "0.5.
|
6
|
+
gem.version = "0.5.5"
|
6
7
|
gem.author = "Daniel J. Berger"
|
7
8
|
gem.email = "djberg96@gmail.com"
|
8
9
|
gem.homepage = "http://www.rubyforge.org/projects/win32utils"
|
9
10
|
gem.platform = Gem::Platform::RUBY
|
10
|
-
gem.summary =
|
11
|
-
gem.description =
|
11
|
+
gem.summary = desc
|
12
|
+
gem.description = desc
|
12
13
|
gem.test_file = "test/tc_process.rb"
|
13
14
|
gem.has_rdoc = true
|
14
15
|
gem.files = Dir["lib/win32/*.rb"] + Dir["test/*"] + Dir["[A-Z]*"]
|
15
16
|
gem.files.reject! { |fn| fn.include? "CVS" }
|
16
17
|
gem.require_path = "lib"
|
17
18
|
gem.extra_rdoc_files = ["README", "CHANGES", "MANIFEST"]
|
18
|
-
gem.add_dependency("windows-pr", ">= 0.7.
|
19
|
+
gem.add_dependency("windows-pr", ">= 0.7.4")
|
19
20
|
end
|
20
21
|
|
21
22
|
if $0 == __FILE__
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: win32-process
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel J. Berger
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2007-
|
12
|
+
date: 2007-12-12 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -19,9 +19,9 @@ dependencies:
|
|
19
19
|
requirements:
|
20
20
|
- - ">="
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version: 0.7.
|
22
|
+
version: 0.7.4
|
23
23
|
version:
|
24
|
-
description: Adds fork, wait, wait2, waitpid,
|
24
|
+
description: Adds create, fork, wait, wait2, waitpid, and a special kill method
|
25
25
|
email: djberg96@gmail.com
|
26
26
|
executables: []
|
27
27
|
|
@@ -69,6 +69,6 @@ rubyforge_project:
|
|
69
69
|
rubygems_version: 0.9.5
|
70
70
|
signing_key:
|
71
71
|
specification_version: 2
|
72
|
-
summary: Adds fork, wait, wait2, waitpid,
|
72
|
+
summary: Adds create, fork, wait, wait2, waitpid, and a special kill method
|
73
73
|
test_files:
|
74
74
|
- test/tc_process.rb
|