###############################################################################
#
# process.eagle --
#
# Extensible Adaptable Generalized Logic Engine (Eagle)
# Eagle Process Package File
#
# Copyright (c) 2007-2012 by Joe Mistachkin. All rights reserved.
#
# See the file "license.terms" for information on usage and redistribution of
# this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# RCS: @(#) $Id: $
#
###############################################################################
#
# NOTE: Use our own namespace here because even though we do not directly
# support namespaces ourselves, we do not want to pollute the global
# namespace if this script actually ends up being evaluated in Tcl.
#
namespace eval ::Eagle {
#
# NOTE: This procedure returns a list of process Ids matching the specified
# name -OR- all process Ids if the specified name is an empty string.
#
proc getProcesses { name } {
#
# NOTE: Start with an empty list of process Ids.
#
set result [list]
#
# NOTE: Are we able to actually query the active processes?
#
if {[llength [info commands object]] > 0} then {
#
# NOTE: Does the caller want processes matching a specific name
# or all processes on the local machine?
#
if {[string length $name] > 0} then {
#
# NOTE: Get the managed array of processes with matching names.
#
set array [object invoke -alias System.Diagnostics.Process \
GetProcessesByName $name]
} else {
#
# NOTE: Get the managed array of all processes on the local
# machine.
#
set array [object invoke -alias System.Diagnostics.Process \
GetProcesses]
}
} else {
#
# NOTE: No, return nothing.
#
return $result
}
#
# NOTE: For each process in the resulting array, grab the Id.
#
for {set index 0} {$index < [$array Length]} {incr index} {
#
# NOTE: Grab the Nth process array element value using the
# accessor method.
#
set process [$array -alias GetValue $index]
#
# NOTE: Add the Id of the process to the result list. This
# may fail on some versions of Mono.
#
if {[catch {$process Id} id] == 0} then {
lappend result $id
}
#
# NOTE: Get rid of the process object, we no longer need it.
# Technically, it is not a requirement to explicitly
# unset variables that contain object references;
# however, it is useful in helping to document the
# code.
#
unset process; # dispose
}
#
# NOTE: Get rid of the managed array of processes, we no longer
# need it.
#
unset array; # dispose
#
# NOTE: Return the list of process Ids, which may be empty.
#
return $result
}
#
# NOTE: This procedure waits for the specified number of milliseconds for
# processes with the specified Ids to exit (or be terminated).
#
proc waitForProcesses { ids timeout {collect true} } {
#
# NOTE: If requested, run the garbage collector now. This may be
# necessary to successfully wait for processes that are being
# kept alive via runtime callable wrappers for out-of-process
# COM servers (e.g. Excel).
#
if {$collect} then {
debug collect
}
#
# NOTE: Wait for each process in the list to exit.
#
foreach id $ids {
#
# NOTE: Get the process object by its Id. If it does not exist,
# this will raise an error.
#
set result [catch {
set process [object invoke -alias System.Diagnostics.Process \
GetProcessById $id]
}]
#
# NOTE: Were we able to grab the process object?
#
if {$result == 0 && [info exists process]} then {
#
# NOTE: Wait a while for the process to exit.
#
$process WaitForExit $timeout
}
#
# NOTE: Get rid of the process (if we actually obtained it to
# begin with).
#
unset -nocomplain process; # dispose
}
}
#
# NOTE: Provide the Eagle "process" package to the interpreter.
#
package provide Eagle.Process \
[expr {[isEagle] ? [info engine PatchLevel] : "1.0"}]
}