############################################################################### # # 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"}] }