Jump to content

Kill other running instances of same compiled script?


Recommended Posts

Hello,

I'm writing a script that, in some circumstances, fails to exit properly, and continues to run as a subprocess of two or more separate instances of CMD.EXE. Until I figure out why that occurs, I want to add a function to the script that kills all other running instances of the same program.

Starting with the excellent and efficient code here:

I've put together this:

_ProcessCloseOtherEx(@ScriptName)

Func _ProcessCloseOtherEx($sPID)
If IsString($sPID) Then $sPID = ProcessExists($sPID)
If Not $sPID Then Return SetError(1, 0, 0)
If $sPID <> @AutoItPID Then
  Return Run(@ComSpec & " /c taskkill /F /PID " & $sPID & " /T", @SystemDir, @SW_HIDE)
Else
  Return
EndIf
EndFunc   ;==>_ProcessCloseOtherEx

As far as I can tell, this seems to work. But I can't figure out a way to make it close more than one other running instance, in case two or more other instances are already running when this one starts. I realize that it shouldn't happen that two instances can be running, but weird things can happen.

I can see that the function needs a While/Wend loop, but I haven't been able to write one that works.

I realize that this is a beginner's question, and I'll be very grateful for any help.

Edited by emendelson
Link to comment
Share on other sites

Let's try recursion:

_ProcessCloseOtherEx(@ScriptName)

Func _ProcessCloseOtherEx($sPID)
    If IsString($sPID) Then $sPID = ProcessExists($sPID)
    
    If Not $sPID Then Return SetError(1, 0, 0)
    
    If $sPID <> @AutoItPID Then
        Run(@ComSpec & " /c taskkill /F /PID " & $sPID & " /T", @SystemDir, @SW_HIDE)
        _ProcessCloseOtherEx($sPID)
    Else
        Return
    EndIf
EndFunc   ;==>_ProcessCloseOtherEx

Note: Untested. If you're CPU asplodes then I am absolved of all responsibility. I had my lawyer write that.

Edit: My lawyer can't spell.

Edited by LaCastiglione
Link to comment
Share on other sites

It's highly unlikely but that could cause a recursion error. Why not use ProcessList instead?

UDF List:

 
_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_ArrayFilter/_ArrayReduce_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_ConvertLHWebColor()/_ConvertSHWebColor()_DesktopDimensions()_DisplayPassword()_DotNet_Load()/_DotNet_Unload()_Fibonacci()_FileCompare()_FileCompareContents()_FileNameByHandle()_FilePrefix/SRE()_FindInFile()_GetBackgroundColor()/_SetBackgroundColor()_GetConrolID()_GetCtrlClass()_GetDirectoryFormat()_GetDriveMediaType()_GetFilename()/_GetFilenameExt()_GetHardwareID()_GetIP()_GetIP_Country()_GetOSLanguage()_GetSavedSource()_GetStringSize()_GetSystemPaths()_GetURLImage()_GIFImage()_GoogleWeather()_GUICtrlCreateGroup()_GUICtrlListBox_CreateArray()_GUICtrlListView_CreateArray()_GUICtrlListView_SaveCSV()_GUICtrlListView_SaveHTML()_GUICtrlListView_SaveTxt()_GUICtrlListView_SaveXML()_GUICtrlMenu_Recent()_GUICtrlMenu_SetItemImage()_GUICtrlTreeView_CreateArray()_GUIDisable()_GUIImageList_SetIconFromHandle()_GUIRegisterMsg()_GUISetIcon()_Icon_Clear()/_Icon_Set()_IdleTime()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsSystemDrive()_IsUPX()_IsValidType()_IsWebColor()_Language()_Log()_MicrosoftInternetConnectivity()_MSDNDataType()_PathFull/GetRelative/Split()_PathSplitEx()_PrintFromArray()_ProgressSetMarquee()_ReDim()_RockPaperScissors()/_RockPaperScissorsLizardSpock()_ScrollingCredits_SelfDelete()_SelfRename()_SelfUpdate()_SendTo()_ShellAll()_ShellFile()_ShellFolder()_SingletonHWID()_SingletonPID()_Startup()_StringCompact()_StringIsValid()_StringRegExpMetaCharacters()_StringReplaceWholeWord()_StringStripChars()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_Create_CTL_CODE()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()Au3 script parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 22/04/2018

Link to comment
Share on other sites

Let's try recursion:

....

Note: Untested. If you're CPU asplodes then I am absolved of all responsibility. I had my lawyer write that.

Edit: My lawyer can't spell.

Thanks for trying to solve this. My CPU didn't explode when I used this function with another instance of the program already running, but I did need to do a hard reset to get out of the recursion. I couldn't even bring up the task manager - although I was able to save all open files.

Maybe that's what's meant by "asploding"? ;-)

Edited by emendelson
Link to comment
Share on other sites

Why not use ProcessList instead?

That sounds like what I would need to do, but unfortunately I'm too much of a beginner to figure it out. Maybe something like this, but clearly I've got this all wrong:

Local $list = ProcessList()
For $i = 1 To $list[0][0]
    If $list[$i][1] = @ScriptName Then
       If $list[$i][1]<> @AutoItPID Then
         ; Kill process
       EndIf
    EndIf
Next

Thanks again for any help.

Link to comment
Share on other sites

You'd want to use something like this:

If $list[$i][0] = @ScriptName Then

Rather than $list[$i][1].

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
Share on other sites

I've writtten an #include file which kills all instances of the script (compiled or not compiled).

;===============================================================================
;
; UDF Name:   _SingleScript.au3
; Description::  close all running scripts with the same name.
; Usage:   #include "_SingleScript.au3"
; Parameter(s):  none
; Requirement(s): none
; Return Value(s): 0
; COPYLEFT:   © 25.05.2008 Freeware
;    ALL WRONGS RESERVED
;
;===============================================================================
;
__SingleScript()
Func __SingleScript()
Local $OI, $O = ObjGet("winmgmts:" & @ComputerName & "rootCIMV2"), $CI = $O.ExecQuery("SELECT * FROM Win32_Process", "WQL", 0x30)
For $OI In $CI
  If $OI.ProcessId = @AutoItPID Then ContinueLoop
  If $OI.Name = StringTrimRight(@ScriptName, 4) & ".EXE" Or ($OI.Name = "AutoIt3.exe" And StringInStr($OI.CommandLine, StringTrimRight(@ScriptName, 4) & ".au3")) Then ProcessClose($OI.ProcessId)
Next
EndFunc   ;==>__SingleScript

OK, there might be a faster way without WMI, but .... those microseconds for one script don't bother me. :-)

The trick is, that the code is called within the include file.

Just put the above code in a file called _singlescript.au3

and put the line

#include '_singlescript.au3'

in front of your script.

Edit: Typo

Edited by forumer100

App: Au3toCmd              UDF: _SingleScript()                             

Link to comment
Share on other sites

Something along these lines >>

_ProcessCloseRunning()

Func _ProcessCloseRunning()
    Local $aArray = ProcessList(@ScriptName)
    For $i = 1 To $aArray[0][0]
        If $aArray[$i][1] = @AutoItPID Then
            ContinueLoop
        EndIf
        $aArray[$i][0] = ProcessClose($aArray[$i][1])
    Next
    Return $aArray
EndFunc   ;==>_ProcessCloseRunning

UDF List:

 
_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_ArrayFilter/_ArrayReduce_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_ConvertLHWebColor()/_ConvertSHWebColor()_DesktopDimensions()_DisplayPassword()_DotNet_Load()/_DotNet_Unload()_Fibonacci()_FileCompare()_FileCompareContents()_FileNameByHandle()_FilePrefix/SRE()_FindInFile()_GetBackgroundColor()/_SetBackgroundColor()_GetConrolID()_GetCtrlClass()_GetDirectoryFormat()_GetDriveMediaType()_GetFilename()/_GetFilenameExt()_GetHardwareID()_GetIP()_GetIP_Country()_GetOSLanguage()_GetSavedSource()_GetStringSize()_GetSystemPaths()_GetURLImage()_GIFImage()_GoogleWeather()_GUICtrlCreateGroup()_GUICtrlListBox_CreateArray()_GUICtrlListView_CreateArray()_GUICtrlListView_SaveCSV()_GUICtrlListView_SaveHTML()_GUICtrlListView_SaveTxt()_GUICtrlListView_SaveXML()_GUICtrlMenu_Recent()_GUICtrlMenu_SetItemImage()_GUICtrlTreeView_CreateArray()_GUIDisable()_GUIImageList_SetIconFromHandle()_GUIRegisterMsg()_GUISetIcon()_Icon_Clear()/_Icon_Set()_IdleTime()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsSystemDrive()_IsUPX()_IsValidType()_IsWebColor()_Language()_Log()_MicrosoftInternetConnectivity()_MSDNDataType()_PathFull/GetRelative/Split()_PathSplitEx()_PrintFromArray()_ProgressSetMarquee()_ReDim()_RockPaperScissors()/_RockPaperScissorsLizardSpock()_ScrollingCredits_SelfDelete()_SelfRename()_SelfUpdate()_SendTo()_ShellAll()_ShellFile()_ShellFolder()_SingletonHWID()_SingletonPID()_Startup()_StringCompact()_StringIsValid()_StringRegExpMetaCharacters()_StringReplaceWholeWord()_StringStripChars()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_Create_CTL_CODE()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()Au3 script parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 22/04/2018

Link to comment
Share on other sites

I've writtten an #include file which kills all instances of the script (compiled or not compiled).

...

That's elegant and complete - and perfect for testing purposes, so I don't have to compile, then test, compile then test, etc.

Thank you!!

Edited by emendelson
Link to comment
Share on other sites

  • 11 months later...
  • 10 months later...

Hello

When I try to run the   _SingleScript.au3 I get an error creating object.

I included this statement to identify an error

Func __SingleScript()
Local $OI, $O = ObjGet("winmgmts:" & @ComputerName & "rootCIMV2")
If @error Then
    MsgBox(0, "Object Test", "Error Getting an Active Object. Error code: " & Hex(@error, 8))
    Exit
EndIf
$CI = $O.ExecQuery("SELECT * FROM Win32_Process", "WQL", 0x30)

 

the error number is 80041002

I am not sure what is means and why it is failing on my machine.  I have updated autoit and scite to the latest version.  Running under win7 x64.

Is there some type of service that needs to be enabled?  Any help is appreciated.

 

 

Link to comment
Share on other sites

Use that handy hidden window every script has :-) your script cannot exist without it.

Func _KillOtherScript()
    Local $i = Opt('WinTitleMatchMode', 3)
    If WinExists(@ScriptFullPath) Then
        Local $hWnd = WinGetHandle(@ScriptFullPath)
        WinClose($hWnd)
    EndIf
    AutoItWinSetTitle(@ScriptFullPath)
    Opt('WinTitleMatchMode', $i)
EndFunc   ;==>_KillOtherScript





















;

 

Edited by Djarlo
Link to comment
Share on other sites

Doesn't seem to work, I can create as many instances of the process as I want

#include <Date.au3>
$t = _NowTime(3)

_KillOtherScript()

MsgBox(0,"Testing Run Once",$t,60)
sleep(1000)

Func _KillOtherScript()

    Local $i = Opt('WinTitleMatchMode', 3)

    If WinExists(@ScriptFullPath) Then
        MsgBox(0,"Killing Previous Instance",$t,60)
        Local $hWnd = WinGetHandle(@ScriptFullPath)

        WinClose($hWnd)

    EndIf

    AutoItWinSetTitle(@ScriptFullPath)

    Opt('WinTitleMatchMode', $i)

EndFunc   ;==>_KillOtherScript
Edited by BattleVena
Link to comment
Share on other sites

msgboxes pause script execution, use a proper loop

_KillOtherScript()
 Func _KillOtherScript()
    Local $i = Opt('WinTitleMatchMode', 3)
    If WinExists(@ScriptFullPath) Then
        Local $hWnd = WinGetHandle(@ScriptFullPath)
        WinClose($hWnd)
    EndIf
    AutoItWinSetTitle(@ScriptFullPath)
    Opt('WinTitleMatchMode', $i)
EndFunc   ;==>_KillOtherScript
While 1
    Sleep(100)
WEnd
Edited by Djarlo
Link to comment
Share on other sites

The script I am killing has build in pause.  This one works although needs to be compiled.

#include <Date.au3>
$t = _NowTime(3)

_KillOtherScript()

MsgBox(0,"Testing Run Once",$t & " " & @AutoItPID  ,60)

func _KillOtherScript()
    Local $list = ProcessList()
    For $i = 1 To $list[0][0]
        If $list[$i][0] = @ScriptName Then
           If $list[$i][1]<> @AutoItPID Then
                ; Kill process
                $r=ProcessClose($list[$i][1])
           EndIf
        EndIf
    Next
EndFunc
Edited by BattleVena
Link to comment
Share on other sites

Hello

 

When I try to run the   _SingleScript.au3 I get an error creating object.

 

I included this statement to identify an error

 

Func __SingleScript()

Local $OI, $O = ObjGet("winmgmts:" & @ComputerName & "rootCIMV2")

If @error Then

    MsgBox(0, "Object Test", "Error Getting an Active Object. Error code: " & Hex(@error, 8))

    Exit

EndIf

$CI = $O.ExecQuery("SELECT * FROM Win32_Process", "WQL", 0x30)

 

 

 

the error number is 80041002

 

I am not sure what is means and why it is failing on my machine.  I have updated autoit and scite to the latest version.  Running under win7 x64.

 

Is there some type of service that needs to be enabled?  Any help is appreciated.

 

Error Code 80041002 - Object Not Found

Try to start WMI in command prompt:

net start Winmgmt

 

Please check if WMI is enabled. For more info see:

http://computerstepbystep.com/windows_management_instrumentation_service.html

 

Edited by Exit

App: Au3toCmd              UDF: _SingleScript()                             

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