Using Kill on Windows 98

SO Oct 14, 2001

Armed with our newly found killexe and tlist.exe programs from MicroSoft: ftp://ftp.microsoft.com/services/technet/samples/ps/win98/reskit/diagnose/

we decided to put them to use in a little tk script:


 wm title . "Win98 Kill-PID"
 wm resizable . 0 1

 #A helper proc -used later with tlist.exe
 proc do_cmd { cmd args } {
        catch {
        set result [eval exec [auto_execok $cmd] $args]
        }
        return $result
 }

 #A procedure to call kill.exe - using a tk_messageBox to verify prior to kill
 proc kill_it {  } {
        global current
        regsub -nocase -all {[a-z\.]} $current "" result
        set check [tk_messageBox -title "Verify Kill Process" -type yesno -icon warning \
                -message "You are about to kill a running process:\n $current \nAre you sure?"]
             
        switch $check {
                        yes { catch { eval exec [auto_execok c:/kill.exe] $result }
                 }
                        no { return }
                }      
        set current {}
        .list delete 0 end
        refresh .list
 }

 #Gets the selected pid and description from the listbox
 proc get_index { w } {
        global current win_pid
        catch {
                set current [lindex $win_pid [$w curselection]]
        }
        .top.button configure -text $current
        return $current
 }

 #Get the pid list using tlist.exe - there must be a better way to do the formatting...
 proc refresh { w } {
        global win_pid current
        .list delete 0 end
        set win_pid { }
        set result [do_cmd c:/tlist.exe]
        set result [split $result -]
        set result [string trimleft $result]
        set result [lreplace $result 0 0]
        foreach index $result {
                lappend win_pid [string trimright -$index]
                }     
        #  win_pid [string trimright -$index]
        foreach index $win_pid {
                $w insert end $index
                }
        .top.label configure -text "There are [llength $win_pid] processes currently running."
        return $win_pid
 }

 #Build the GUI
 proc make_GUI { } {
        frame .top
        button .top.button -width 50 -relief groove  -textvariable current \
                -font system -command {kill_it }
        label .top.label
        listbox .list -height 10 -width 50 -yscrollcommand ".scrl set" \
                -bg white -font system
        scrollbar .scrl -command ".list yview"
        pack .top
        pack .top.button
        pack .top.label
        pack .scrl -side right -fill y
        pack .list -side left -expand 1 -fill y
        bind .list <ButtonRelease-1> { get_index %W }
 }

 
 proc main { } {
        make_GUI
        refresh .list
 }

 main

I probably should have added a proc to keep the list current, but is it *REALLY* late, maybe tomorrow...

Is this sort of like the Windows ME/Windows NT Task Manager?

I suppose it is, there is a task manager on win 9x also

My apologies to anyone who has copied the script and had problems. It appears to have gotten mangled somehow over the weekend. It is okay now..


AM (22 february 2005) We ran into a problem with an automated testbench: programs that did something nasty (like a memory access violation) would produce a message box that would only go away with a click on the OK button (I cannot refrain from making a comment about that label: there is nothing OK about that!).

It seems (untested at the moment, but the information may be relevant in another context) that the registry key "AeDebug" controls what happens (http://support.microsoft.com/kb/188296/EN-US/ ):

   HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\ AeDebug

If you delete it, you disable any possible debugger from starting (and we hope it will do away with the messagebox too)

Here is the full description of the problem as I put it on the comp.lang.tcl newsgroup:

Hello,

I would like to ask you about a rather nasty property of Windows: Sometimes when a program does something it should not, Windows helpfully puts up a message box stating that fact and then the process waits for confirmation by the user.

One can argue that this is user-friendly behaviour ... You get to see that something went extraordinarily wrong.

In our situation it is simply a nuisance:

  • We run a bunch of programs with varying input via Tcl scripts to make sure they work alright (with all this varying input).
  • If such a crash occurs on Linux, we can detect it because the catch/exec combination sees that things are written to standard-error.
  • Because of the message box, the process does not terminate. The surrounding script stops and the whole system patiently waits for the user to come in again in the morning (possibly a monday morning, because the total time required can be fairly long, so we would like things to run over the weekend).

My questions:

  • Does anybody know of a solution to this?
  • Is it possible to detect this situation from the outside?

Note: the processes are not run in the background, but we could probably arrange for that to happen. Or we can run another script that will take the actions needed to make the process go away...

Regards,

Arjen

Update: Perhaps this fragment of code is even more to the point:

 /* exitcodes: 0 == no, 1 == yes, 2 == error */
 int 
 main (int argc, char *argv[])
 {
     char msg[300];
     DWORD dwWritten;
     int chars;

     /* make sure children (cl.exe and link.exe) are kept quiet. */
     SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX); 

(from the file tcl/win/nmakehlp.c - thanks to Pat Thoyts)


LES: the best I think of is PowerPro. It can detect the title and even the content of practically any window and react to it. Among its possible reactions, you could use "send keys" and send {Enter} to the pop-up.