Jump to content

How can i close all process of running script except current process(@autoitpid)?


Recommended Posts

How can i close all process of running script except @autoitpid?

#include <GUIConstants.au3>
#include <Constants.au3>
#include <Array.au3>

Opt("TrayOnEventMode",1)
Opt("TrayAutoPause",0)

    If UBound(ProcessList(@ScriptName)) > 2 Then
    $prslist = ProcessList(@ScriptName)
    For $i = 1 To $prslist[0][0] - 1 ;In array current @AutoItPID always last so i subtract 1 but no benefit.

        Do
        ProcessClose($prslist[$i][0])
        Until Not ProcessExists($prslist[$i][1])
        MsgBox(0,"ERROR","An Error occurred Please Run it Again After Few Seconds")
        Sleep(100)
        Exit
    Next
    Exit
EndIf

$process = ProcessList(@ScriptName)
_ArrayDisplay($process)
MsgBox(0,"",@AutoItPID)
$Gui = GUICreate('whatever',300,300)
guisetstate()
TraySetOnEvent($TRAY_EVENT_PRIMARYDOWN, "max")
While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            GUISetState(@SW_MINIMIZE, $Gui)
            GUISetState(@SW_HIDE, $Gui)
    EndSwitch
Wend

Func max()
    GUISetState(@SW_RESTORE, $Gui)
    GUISetState(@SW_SHOW, $Gui)
EndFunc

Processlist() and processclose() function work after compiling. Because @scriptname result before compiling is (XXXX.au3) main while process creates with name of AutoIt3.exe.

Edited by Starstar

Life is like a coin. You can spend it Anyway as you wish and for your kind information. "you can spend it only once."

Link to comment
Share on other sites

You are sure that the current process is always the last in the array? I would check all entries in the array and compare the processid with @autoitpid and close all but @autoitpid.

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2022-02-19 - Version 1.6.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (NEW 2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki

Standard UDFs:
Excel - Example Scripts - Wiki
Word - Wiki

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to comment
Share on other sites

Wouldn't it make more sense to inhibit starting a new instance of the script while it is already running? Check _Singleton for this.

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2022-02-19 - Version 1.6.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (NEW 2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki

Standard UDFs:
Excel - Example Scripts - Wiki
Word - Wiki

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to comment
Share on other sites

Wouldn't it make more sense to inhibit starting a new instance of the script while it is already running? Check _Singleton for this.

​Ok Thanks Water it is looking something helpful... i am going to try.......

Life is like a coin. You can spend it Anyway as you wish and for your kind information. "you can spend it only once."

Link to comment
Share on other sites

Thanks @Water i can use Singleton to detect that there is already running a process. But i shall ask the same question again How can i close old process.........?

$sProcess = _Singleton("AutoIt3.exe",1)
If $sProcess = 0 Then
    ProcessClose("Old process"); problem is here
    MsgBox(0, "Warning", "An occurence of test is already running")
EndIf
Edited by Starstar

Life is like a coin. You can spend it Anyway as you wish and for your kind information. "you can spend it only once."

Link to comment
Share on other sites

It's even simpler. Use something like this to prevent a second instance to be started:

_Singleton("YourNameForThisScript")

This immediately exists the script when there is already an instance of the same script with the same identifier ("YourNameForThisScript") active. The identifier does not have to be the name of the exe.

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2022-02-19 - Version 1.6.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (NEW 2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki

Standard UDFs:
Excel - Example Scripts - Wiki
Word - Wiki

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to comment
Share on other sites

Just use _SingleScript() function:

#include <_SingleScript.au3>
_SingleScript()
MsgBox(Default, Default, "No other script with name " & StringTrimRight(@ScriptName, 4) & " is executing any more.", 0)

 

 

_SingleScript.au3  include file:
 

#include-once

;==============================================================================================================
; UDF Name:         _SingleScript.au3
; Description:      iMode=0  Close all executing scripts with the same name and continue.
;                   iMode=1  Wait for completion of predecessor scripts with the same name.
;                   iMode=2  Exit if other scripts with the same name are executing.
;                   iMode=3  Test, if other scripts with the same name are executing.
;
; Syntax:           _SingleScript([iMode=0])
;                   Default:  iMode=0
; Parameter(s):     iMode:     0/1/2/3    see above

; Requirement(s):   none

; Return Value(s): -1= error      @error=-1   invalid iMode

;                   0= no other script executing @error=0 @extended=0
;                   1= other script executing @error=0 @extended=1 (only iMode=3)
; Example:
;               #include <_SingleScript.au3>
;               _SingleScript() ; Close mode ( iMode defaults to 0 )
;               MsgBox(Default, Default, "No other script with name " & StringTrimRight(@ScriptName, 4) & " is executing.", 0)
;               ; see other example at end of this UDF
;
; Author:       Exit   ( http://www.autoitscript.com/forum/user/45639-exit )
; COPYLEFT:     © 2013 Freeware by "Exit"
;               ALL WRONGS RESERVED
;==============================================================================================================

Func _SingleScript($iMode = 0)
    Local $oWMI, $oProcess, $oProcesses, $aHandle, $aError, $sMutexName = "_SingleScript " & StringTrimRight(@ScriptName, 4)
    If $iMode < 0 Or $iMode > 3 Then Return SetError(-1, -1, -1)
    If $iMode = 0 Or $iMode = 3 Then ; (iMode = 0) close all other scripts with the same name.  (iMode = 3) check, if others are running.
        $oWMI = ObjGet("winmgmts:\\" & @ComputerName & "\root\CIMV2")
        If @error Then

            RunWait(@ComSpec & ' /c net start winmgmt  ', '', @SW_HIDE)
            RunWait(@ComSpec & ' /c net continue winmgmt  ', '', @SW_HIDE)
            $oWMI = ObjGet("winmgmts:\\" & @ComputerName & "\root\CIMV2")
        EndIf

        $oProcesses = $oWMI.ExecQuery("SELECT * FROM Win32_Process", "WQL", 0x30)
        For $oProcess In $oProcesses

            If $oProcess.ProcessId = @AutoItPID Then ContinueLoop

            If Not ($oProcess.Name = StringTrimRight(@ScriptName, 4) & ".EXE" Or ($oProcess.Name = "AutoIt3.exe" And StringInStr($oProcess.CommandLine, StringTrimRight(@ScriptName, 4) & ".au3"))) Then ContinueLoop

            If $iMode = 3 Then Return SetError(0, 1, 1) ; indicate other script is running. Return value and @extended set to 1.
            If ProcessClose($oProcess.ProcessId) Then ContinueLoop

            MsgBox(262144, "Debug " & @ScriptName, "Error: " & @error & " Extended: " & @extended & @LF & "Processclose error: " & $oProcess.Name & @LF & "******", 0)
        Next
        Sleep(100) ; allow process to terminate

    EndIf



    $aHandle = DllCall("kernel32.dll", "handle", "CreateMutexW", "struct*", 0, "bool", 1, "wstr", $sMutexName) ; try to create Mutex

    $aError = DllCall("kernel32.dll", "dword", "GetLastError") ; retrieve last error

    If Not $aError[0] Then Return SetError(0, 0, 0)
    If $iMode = "2" Then Exit 1
    If $iMode = "0" Then Return SetError(1, 0, 1) ; should not occur

    DllCall("kernel32.dll", "dword", "WaitForSingleObject", "handle", $aHandle[0], "dword", -1) ; infinite wait for lock
    Return SetError(0, 0, 0)
EndFunc   ;==>_SingleScript



#comments-start     Here is the other example. Uncomment and use TIDY to reformat.
    #include <_SingleScript.au3>
    If $cmdline[0] = 0 Then ; submit all scripts

    TraySetToolTip("No Case")
    _SingleScript() ; Kill other scripts, if others are executing

    For $i = 0 To 7
    Sleep(100)
    ShellExecute(@ScriptFullPath, $i)
    Next
    Exit MsgBox(64 + 262144, Default, "All scripts submitted. See icons in system tray. Case 1 already disappeared.", 0)
    EndIf

    TraySetToolTip("Case " & $cmdline[1])
    Switch $cmdline[1]
    Case 0
    $rc = _SingleScript(3) ; Check, if others are executing

    MsgBox(64 + 262144, Default, "Case " & $cmdline[1] & " executing. " & ($rc ? "Some" : "No") & " other scripts executing.", 0)
    Case 1
    _SingleScript(2) ; Kill this scropt, if others are executing

    Beep(440, 3000) ; you will NOT hear the long beep.
    Case 2, 3, 4, 6, 7
    _SingleScript(1) ; Wait for predecessors completed

    MsgBox(64 + 262144, Default, "Case " & $cmdline[1] & " executing.", 0)
    Case 5
    _SingleScript(1) ; Wait for predecessors completed (case 1-4)
    MsgBox(64 + 262144, Default, "Case " & $cmdline[1] & " executing." & @CRLF & "Now killing other scripts. See icons in system tray.", 0)
    _SingleScript() ; Now kill other scripts. Should be case 6 and 7
    _SingleScript(3) ; Check, if others are executing

    MsgBox(64 + 262144, Default, "Case " & $cmdline[1] & " executing. " & (@extended ? "Some" : "No") & " other scripts executing.", 0)
    EndSwitch

#comments-end

 

App: Au3toCmd              UDF: _SingleScript()                             

Link to comment
Share on other sites

For the OP question :

$sScriptName = @Compiled ? @ScriptName : StringRegExpReplace(@AutoItExe, ".+\\", "")

While 1
    $aList = ProcessList($sScriptName)
    If $aList[0][0] = 1 Then ExitLoop
    For $i = 1 To $aList[0][0]
        If $aList[$i][1] <> @AutoItPID Then ProcessClose($aList[$i][1])
    Next
WEnd

An alternative to _Singleton based on the program name :

$sScriptName = @Compiled ? @ScriptName : StringRegExpReplace(@AutoItExe, ".+\\", "")
If UBound(ProcessList($sScriptName)) > 2 Then Exit

 

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...