Jump to content

Process detection/taskkill malfunction


herr5407
 Share

Recommended Posts

Hi all,

I've recently come across AutoIT about 2 weeks ago and I don't have a programming background so please forgive if my code is sloppy (which it is) and things aren't as efficient as they could be.

My problem is I have wrote a small GUI that will basically detect which ever processes that you enter into the array. Everything seems to be working except one part. I can get the detections to work and display in the list properly and also, if it only detects one program it will terminate it properly. The problem is when more than one program is detected, the button doesn't even appear to call the function. I'm sure it's just a logic error somewhere that I cannot see.

Any help would be appreciated very much.

#include <GuiConstantsEx.au3>

; VARIABLES AND ARRAYS
;------------------------------------------------------
$timer1=11;Must be 1 less than declared $prog

local $prog[12]
$prog[0]="1.exe"
$prog[1]="2.exe"
$prog[2]="3.exe"
$prog[3]="4.exe"
$prog[4]="5.exe"
$prog[5]="6.exe"
$prog[6]="7.exe"
$prog[7]="8.exe"
$prog[8]="9.exe"
$prog[9]="10.exe"
$prog[10]="11.exe"
$prog[11]="notepad.exe"
;$prog[11]="mspaint.exe"

local $det[12]
$det[0]=False
$det[1]=False
$det[2]=False
$det[3]=False
$det[4]=False
$det[5]=False
$det[6]=False
$det[7]=False
$det[8]=False
$det[9]=False
$det[10]=False
$det[11]=False

; GUI CREATE
;------------------------------------------------------
GuiCreate("Deeeestroy GUI", 400, 400)

; PROCESS DETECTION
;------------------------------------------------------
while $timer1 >= 0
    if ProcessExists($prog[$timer1]) Then
        $det[$timer1] = True
    Else
        $det[$timer1] = False
        EndIf
    $timer1 = $timer1 - 1
    WEnd

; GENERATE LIST VIEW / DISPLAY RESULTS
;------------------------------------------------------
$listView = GuiCtrlCreateListView("Process              |Detected?",1,1,399,200)
$timer1=11;TIMER RESET
while $timer1 >= 0  
GuiCtrlCreateListViewItem(""& $prog[$timer1]& "|"& $det[$timer1] & "", $listView)
$timer1 = $timer1 - 1
wend

; DISPLAY TERMINATE BUTTON IF $det[x] = True
;------------------------------------------------------
$killbutton=123213;If this is not declared, it get an error.......
$timer1 = 11;TIMER RESET
while $timer1 >= 0
    if $det[$timer1] = True Then
        $killbutton = GUICtrlCreateButton("Terminate",7,210,70)
    endif
    $timer1 = $timer1 - 1
WEnd

; FUNCTIONS
;------------------------------------------------------
Func toast()
    $timer1=11;TIMER RESET
    while $timer1 >= 0
    run('taskkill /f /im ' & $prog[$timer1],"",@SW_HIDE)
    $timer1 = $timer1 - 1
WEnd
msgbox(0,"Completed","Completed closures")
EndFunc

Func _killbutton($sFlag = 0)
    If $sFlag = 1 Then
        toast()
    EndIf
EndFunc

; GUI MESSAGE LOOP
;------------------------------------------------------
GuiSetState()

While 1
    $msg = GUIGetMsg()
    Switch $msg
        Case $killbutton
            _killbutton(1)
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
WEnd
Edited by herr5407
Link to comment
Share on other sites

Some things to tweak:

1. Ditch this whole $timer thing with the While/WEnd loops. Just use a basic For/Next loop.

2. When you want the size of an array, just use Ubound(), not a static variable with the array size in it:

Example:

For $n = 0 to UBound($prog) - 1
    GUICtrlCreateListViewItem("" & $prog[$n] & "|" & $det[$n] & "", $listView)
Next

3. Use RunWait() vice Run() so the script will pause until the KILL is completed:

Func _killbutton()
    For $n = 0 To UBound($prog) - 1
        RunWait('taskkill /f /im ' & $prog[$n], "", @SW_HIDE)
    Next
EndFunc  ;==>_killbutton

4. Presumably you only want to kill the processes that were detected, so that could become:

Func _killbutton()
    For $n = 0 To UBound($prog) - 1
        If $det[$n] Then 
            RunWait('taskkill /f /im ' & $prog[$n], "", @SW_HIDE)
        EndIf
    Next
EndFunc  ;==>_killbutton

:mellow:

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

hmm. I made all the changes and scrapped the while loops. Still doesn't run taskkill on button click when there is more than one process detected.... Works just fine when only a single one is though still

Replace from: External Program, TaskKill.exe /f /im image_name

Replace to: Internal Function, ProcessClose( PID )

About ProcessList( "" ) FOR loop;

Replace from: Pre-defined Deny-List

Replace to: Pre-defined Allow-List

It is more flexible.

Bad Example:

$var[3] = ["danger.exe" , "hacktool.exe" , "keylogger.exe"]

For ^ If ProcessExists( PID ) >= 1 ^ ProcessClose( PID )

Good Example:

$var = ProcessList( "" )

For ^ Switch pName ^ Case "good.exe" => $Allow = 1 ^ Case "myProgram.exe" => $Allow = 1 ^ Case Else => $Allow = 0 ^ If $Allow = 0 => ProcessClose( PID )

Link to comment
Share on other sites

hmm. I made all the changes and scrapped the while loops. Still doesn't run taskkill on button click when there is more than one process detected.... Works just fine when only a single one is though still

Can you post the current version?

:mellow:

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

Sure can.

#include <GuiConstantsEx.au3>

; VARIABLES AND ARRAYS
;------------------------------------------------------
Local $prog[12]
$prog[0]="1.exe"
$prog[1]="2.exe"
$prog[2]="3.exe"
$prog[3]="4.exe"
$prog[4]="5.exe"
$prog[5]="6.exe"
$prog[6]="7.exe"
$prog[7]="8.exe"
$prog[8]="9.exe"
$prog[9]="10.exe"
$prog[10]="11.exe"
$prog[11]="12.exe"
;$prog[10]="mspaint.exe"
;$prog[11]="notepad.exe"

Local $det[12]
$det[0]=False
$det[1]=False
$det[2]=False
$det[3]=False
$det[4]=False
$det[5]=False
$det[6]=False
$det[7]=False
$det[8]=False
$det[9]=False
$det[10]=False
$det[11]=False

;Service detection arrays - keep in mind each entry in the array has to match from exe to service name
Local $svcname[1]
$svcname[0]="Bonjour Service"

local $svcdet[1]
$svcdet[0]="mDNSResponder.exe"

local $svcflag[1]
$svcflag[0]=False

; GUI CREATE
;------------------------------------------------------
GuiCreate("Deeeestroy GUI", 400, 450)

; PROCESS DETECTION
;------------------------------------------------------
For $n = 0 to Ubound($det) - 1
    if processexists($prog[$n]) Then
        $det[$n] = True
    Else
        $det[$n] = False
    EndIf
Next

; SERVICE DETECTION
;------------------------------------------------------
For $n = 0 to ubound($svcdet) - 1
    if processexists($svcdet[$n]) Then
        $svcflag[$n]=True
    Else
        $svcflag[$n]=False
    EndIf
Next

; GENERATE LIST VIEW / DISPLAY RESULTS - PROCESSES
;------------------------------------------------------
$listView = GuiCtrlCreateListView("Process              |Detected?",1,1,399,200)
For $n = 0 to UBound($prog) - 1
    GUICtrlCreateListViewItem("" & $prog[$n] & "|" & $det[$n] & "", $listView)
Next

; GENERATE LIST VIEW / DISPLAY RESULTS - SERVICES
;------------------------------------------------------
$listView2 = GuiCtrlCreateListView("Process                        |Service Name                  |Detected?",1,250,399,150)
For $n = 0 to Ubound($svcdet) - 1
    GUICtrlCreateListViewItem("" & $svcdet[$n] & "|" & $svcname[$n] & "|" & $svcflag[$n] &"", $listview2)
Next

; DISPLAY TERMINATE BUTTON IF $det[x] = True
;------------------------------------------------------
For $n=11 to Ubound($det) - 1;If I change $n=11 (one less then declared array) then it will close all of the detected processes. If it = 0, it wont do anything if it detects more than one.
    if $det[$n] = true Then
        $killbutton = GUICtrlCreateButton("Terminate",7,210,70)
    Else
        $killbutton = 1
        endif
Next

; FUNCTIONS
;------------------------------------------------------
Func _killbutton()
    For $n = 0 To UBound($det) - 1
        If $det[$n] = true Then 
            ProcessClose($prog[$n])
        EndIf
    Next
EndFunc

; GUI MESSAGE LOOP
;------------------------------------------------------
GuiSetState()

While 1
    $msg = GUIGetMsg()
    Switch $msg
        Case $killbutton
            _killbutton()
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
WEnd

Basically even after making them, it refused to run the terminate when there was more than one detected. Basically I figured out it was something with how the button was being created. If I change $n=11 on the "DISPLAY TERMINATE BUTTON IF $det[x] = True" section (one less then declared array) then it will close all of the detected processes. If it = 0, it wont do anything if it detects more than one.

As well, if it detects one process in the middle of the array, it won't close even display the button so it's how I have the button appear. It's not checking the entire array for True statements. It stops somewhere.

Link to comment
Share on other sites

G'day herr5407

I'm new to AutoIT myself but it would appear that you maybe creating multiple Kill buttons

For $n=11 to Ubound($det) - 1;If I change $n=11 (one less then declared array) then it will close all of the detected processes. If it = 0, it wont do anything if it detects more than one.
    if $det[$n] = true Then
        $killbutton = GUICtrlCreateButton("Terminate",7,210,70)
    Else
        $killbutton = 1
        endif
Next

This code will execute

$killbutton = GUICtrlCreateButton("Terminate",7,210,70)
for every detection. As well as only checking items 11 to 11. Thats why it's working now as you only check one item.

There are 2 ways to fix it :

Set the FOR to check ALL of the items in the array but use a flag to detect if the button is already created. IE Only create the button once.

OR :mellow:

Set a flag to TRUE when you set one of the array elements to TRUE then use a simple IF statement to create the button once.

That is what I've done below and it appears to work.

#include <GuiConstantsEx.au3>

local $displayKillButton = False

; VARIABLES AND ARRAYS
;------------------------------------------------------
Local $prog[12]
$prog[0]="1.exe"
$prog[1]="2.exe"
$prog[2]="3.exe"
$prog[3]="4.exe"
$prog[4]="5.exe"
$prog[5]="6.exe"
$prog[6]="7.exe"
$prog[7]="8.exe"
$prog[8]="9.exe"
$prog[9]="10.exe"
$prog[10]="11.exe"
$prog[11]="12.exe"
$prog[10]="mspaint.exe"
$prog[11]="notepad.exe"

Local $det[12]
$det[0]=False
$det[1]=False
$det[2]=False
$det[3]=False
$det[4]=False
$det[5]=False
$det[6]=False
$det[7]=False
$det[8]=False
$det[9]=False
$det[10]=False
$det[11]=False

;Service detection arrays - keep in mind each entry in the array has to match from exe to service name
Local $svcname[1]
$svcname[0]="Bonjour Service"

local $svcdet[1]
$svcdet[0]="mDNSResponder.exe"

local $svcflag[1]
$svcflag[0]=False

; GUI CREATE
;------------------------------------------------------
GuiCreate("Deeeestroy GUI", 400, 450)

; PROCESS DETECTION
;------------------------------------------------------
For $n = 0 to Ubound($det) - 1
    if processexists($prog[$n]) Then
        $det[$n] = True
        $displayKillButton = True
    Else
        $det[$n] = False
    EndIf
Next

; SERVICE DETECTION
;------------------------------------------------------
For $n = 0 to ubound($svcdet) - 1
    if processexists($svcdet[$n]) Then
        $svcflag[$n]=True
        $displayKillButton = True
    Else
        $svcflag[$n]=False
    EndIf
Next

; GENERATE LIST VIEW / DISPLAY RESULTS - PROCESSES
;------------------------------------------------------
$listView = GuiCtrlCreateListView("Process              |Detected?",1,1,399,200)
For $n = 0 to UBound($prog) - 1
    GUICtrlCreateListViewItem("" & $prog[$n] & "|" & $det[$n] & "", $listView)
Next

; GENERATE LIST VIEW / DISPLAY RESULTS - SERVICES
;------------------------------------------------------
$listView2 = GuiCtrlCreateListView("Process                        |Service Name                  |Detected?",1,250,399,150)
For $n = 0 to Ubound($svcdet) - 1
    GUICtrlCreateListViewItem("" & $svcdet[$n] & "|" & $svcname[$n] & "|" & $svcflag[$n] &"", $listview2)
Next

; DISPLAY TERMINATE BUTTON IF $det[x] = True
;------------------------------------------------------
;For $n=11 to Ubound($det) - 1;If I change $n=11 (one less then declared array) then it will close all of the detected processes. If it = 0, it wont do anything if it detects more than one.
;   if $det[$n] = true Then
;       $killbutton = GUICtrlCreateButton("Terminate",7,210,70)
;   Else
;       $killbutton = 1
;       endif
;Next

if $displayKillButton Then
    $killbutton = GUICtrlCreateButton("Terminate",7,210,70)
EndIf

; FUNCTIONS
;------------------------------------------------------
Func _killbutton()
    For $n = 0 To UBound($det) - 1
        If $det[$n] = true Then 
            ProcessClose($prog[$n])
        EndIf
    Next
EndFunc

; GUI MESSAGE LOOP
;------------------------------------------------------
GuiSetState()

While 1
    $msg = GUIGetMsg()
    Switch $msg
        Case $killbutton
            _killbutton()
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
WEnd

ONE other thing bring up a msgbox when the KILLS have been done there is no indication that anything has happened.

Good Luck

John Morrison

Edited by storme
Link to comment
Share on other sites

Thanks! I'll check er out tomorrow. Flu has been keeping me sedated and sleeping fairly early.

I just put the service detection in there for fun. I'll slowly expand the script until I have a utility eventually. No better way to learn I guess!

Link to comment
Share on other sites

G'day again

I just couldn't keep my sticky fingers off your program. :\

Here is an "improvement" (IMHO) :mellow: to your detailing of the programs to shut down. I've simply used the stringsplit function to automatically size and create the arrays for you. This reduces potential errors and lends itself to using an INI file (You only need one item in the INI to specify the programs) in the future if you want to go that way. Take note of the use of "$prog[0]".... GOD I love this language....SOOO EASY...LOL

BTW I didn't change the "Service" section, thought you may have wanted to do that yourself. If you think this is a good idea.

#include <GuiConstantsEx.au3>

local $displayKillButton = False

; VARIABLES AND ARRAYS
;------------------------------------------------------
Local $programs = "1.exe, 2.exe,3.exe,4.exe,5.exe,6.exe,7.exe,notepad.exe,8.exe,9.exe,10.exe,11.exe,12.exe,mspaint.exe"
Local $prog = StringSplit($programs, ",")
Local $det[$prog[0]+1]


;Service detection arrays - keep in mind each entry in the array has to match from exe to service name
Local $svcname[1]
$svcname[0]="Bonjour Service"

local $svcdet[1]
$svcdet[0]="mDNSResponder.exe"

local $svcflag[1]
$svcflag[0]=False

; GUI CREATE
;------------------------------------------------------
GuiCreate("Deeeestroy GUI", 400, 450)

; PROCESS DETECTION
;------------------------------------------------------
For $n = 1 to $prog[0]
    if processexists($prog[$n]) Then
        $det[$n] = True
        $displayKillButton = True
    Else
        $det[$n] = False
    EndIf
Next

; SERVICE DETECTION
;------------------------------------------------------
For $n = 0 to ubound($svcdet) - 1
    if processexists($svcdet[$n]) Then
        $svcflag[$n]=True
        $displayKillButton = True
    Else
        $svcflag[$n]=False
    EndIf
Next

; GENERATE LIST VIEW / DISPLAY RESULTS - PROCESSES
;------------------------------------------------------
$listView = GuiCtrlCreateListView("Process              |Detected?",1,1,399,200)
For $n = 1 to $prog[0]
    GUICtrlCreateListViewItem("" & $prog[$n] & "|" & $det[$n] & "", $listView)
Next

; GENERATE LIST VIEW / DISPLAY RESULTS - SERVICES
;------------------------------------------------------
$listView2 = GuiCtrlCreateListView("Process                        |Service Name                  |Detected?",1,250,399,150)
For $n = 0 to Ubound($svcdet) - 1
    GUICtrlCreateListViewItem("" & $svcdet[$n] & "|" & $svcname[$n] & "|" & $svcflag[$n] &"", $listview2)
Next

; DISPLAY TERMINATE BUTTON IF $det[x] = True
;------------------------------------------------------
;For $n=11 to Ubound($det) - 1;If I change $n=11 (one less then declared array) then it will close all of the detected processes. If it = 0, it wont do anything if it detects more than one.
;   if $det[$n] = true Then
;       $killbutton = GUICtrlCreateButton("Terminate",7,210,70)
;   Else
;       $killbutton = 1
;       endif
;Next

if $displayKillButton Then
    $killbutton = GUICtrlCreateButton("Terminate",7,210,70)
Else
    $killbutton = ""
EndIf

; FUNCTIONS
;------------------------------------------------------
Func _killbutton()
    For $n = 1 To $prog[0]
        If $det[$n] = true Then 
            ProcessClose($prog[$n])
        EndIf
    Next
EndFunc

; GUI MESSAGE LOOP
;------------------------------------------------------
GuiSetState()

While 1
    $msg = GUIGetMsg()
    Switch $msg
        Case $killbutton
            _killbutton()
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
WEnd

Just one more suggestion. Think about command line options (ie /Auto) to automatically shut down everything identified and (/silent) to not bring up the GUI.

This is what I use in one of my scripts. Maybe someone else can think up something better.

Global $cmdSwchAuto = False;Run without user intervention
Global $cmdSwchSilent = False;Run without GUI

func parseCommandLine()
    If $cmdline[0] <> 0 Then
; interate through command line looking for options
        local $element
        FOR $element IN $cmdline
            $element = StringUpper($element)
            Select 
                case $element = "-A" or $element = "-AUTO"
                    Global $cmdSwchAuto = True;Run without user intervention
                case $element = "-S" or $element = "-SILENT"
                    Global $cmdSwchSilent = True;Run without GUI            EndSelect
        NEXT
    EndIf
EndFunc

Good Luck

John Morrison

Edited by storme
Link to comment
Share on other sites

Thanks! I think that's what sucked me into AutoIT is the language was very easy to grasp even without a programming background.

I have one question. In the snippet below, why exactly does $n = 1?

For $n = 1 to $prog[0]

and I couldn't get the cmd line function to work properly. Just executes program.

Edited by herr5407
Link to comment
Share on other sites

Thanks! I think that's what sucked me into AutoIT is the language was very easy to grasp even without a programming background.

I have one question. In the snippet below, why exactly does $n = 1?

For $n = 1 to $prog[0]
Because the array was generated with StringSplit(), [0] = count. The first data element is [1], and looping through all elements would be 1 to $prog[0]. Some arrays use [0] for the count and some use it for the first data element. It's up to the scripter to decide how to use it.

and I couldn't get the cmd line function to work properly. Just executes program.

In the snippet posted the function never gets called, just add the call:
Global $cmdSwchAuto = False;Run without user intervention
Global $cmdSwchSilent = False;Run without GUI
parseCommandLine()

func parseCommandLine()
    If $cmdline[0] <> 0 Then
       ; interate through command line looking for options
        local $element
        FOR $element IN $cmdline
            $element = StringUpper($element)
            Select
                case $element = "-A" or $element = "-AUTO"
                    Global $cmdSwchAuto = True; Run without user intervention
                case $element = "-S" or $element = "-SILENT"
                    Global $cmdSwchSilent = True; Run without GUI
            EndSelect
        NEXT
    EndIf
EndFunc

Still, all it does is set some global variables for the rest of your script to reference, so you won't see anything happen by running just that.

:mellow:

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

In the snippet posted the function never gets called, just add the call:

Global $cmdSwchAuto = False;Run without user intervention
Global $cmdSwchSilent = False;Run without GUI
parseCommandLine()

func parseCommandLine()
    If $cmdline[0] <> 0 Then
      ; interate through command line looking for options
        local $element
        FOR $element IN $cmdline
            $element = StringUpper($element)
            Select
                case $element = "-A" or $element = "-AUTO"
                    Global $cmdSwchAuto = True; Run without user intervention
                case $element = "-S" or $element = "-SILENT"
                    Global $cmdSwchSilent = True; Run without GUI
            EndSelect
        NEXT
    EndIf
EndFunc
Exactly I didn't want to take over the project just give a helping hand and a few pointers (Where I can).

Still, all it does is set some global variables for the rest of your script to reference, so you won't see anything happen by running just that.

:)

Yeah I should have siad that in the original message. :)

The variables must be used in your code to do something.

eg

if $cmdSwchAuto then
   ; call the process kill routine
endif

if not $cmdSwchAuto then
   ; place GUI code here
endif

Let me know if you need any help with this.

Good Luck

John Morrison

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...