emendelson Posted January 3, 2012 Posted January 3, 2012 (edited) 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 ;==>_ProcessCloseOtherExAs 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 January 3, 2012 by emendelson
jaberwacky Posted January 3, 2012 Posted January 3, 2012 (edited) 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 ;==>_ProcessCloseOtherExNote: 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 January 3, 2012 by LaCastiglione Helpful Posts and Websites: AutoIt3 Variables and Function Parameters MHz | AutoIt Wiki | Using the GUIToolTip UDF BrewManNH | Can't find what you're looking for on the Forum?
guinness Posted January 3, 2012 Posted January 3, 2012 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 parsing • AutoIt Search • AutoIt3 Portable • AutoIt3WrapperToPragma • AutoItWinGetTitle()/AutoItWinSetTitle() • Coding • DirToHTML5 • FileInstallr • FileReadLastChars() • GeoIP database • GUI - Only Close Button • GUI Examples • GUICtrlDeleteImage() • GUICtrlGetBkColor() • GUICtrlGetStyle() • GUIEvents • GUIGetBkColor() • Int_Parse() & Int_TryParse() • IsISBN() • LockFile() • Mapping CtrlIDs • OOP in AutoIt • ParseHeadersToSciTE() • PasswordValid • PasteBin • Posts Per Day • PreExpand • Protect Globals • Queue() • Resource Update • ResourcesEx • SciTE Jump • Settings INI • SHELLHOOK • Shunting-Yard • Signature Creator • Stack() • Stopwatch() • StringAddLF()/StringStripLF() • StringEOLToCRLF() • VSCROLL • WM_COPYDATA • More Examples... Updated: 22/04/2018
jaberwacky Posted January 3, 2012 Posted January 3, 2012 How can you have any fun if you don't take chances? Helpful Posts and Websites: AutoIt3 Variables and Function Parameters MHz | AutoIt Wiki | Using the GUIToolTip UDF BrewManNH | Can't find what you're looking for on the Forum?
emendelson Posted January 3, 2012 Author Posted January 3, 2012 (edited) 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 January 3, 2012 by emendelson
emendelson Posted January 3, 2012 Author Posted January 3, 2012 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.
BrewManNH Posted January 3, 2012 Posted January 3, 2012 You'd want to use something like this:If $list[$i][0] = @ScriptName ThenRather 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 GudeHow 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
Exit Posted January 3, 2012 Posted January 3, 2012 (edited) 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 January 3, 2012 by forumer100 App: Au3toCmd UDF: _SingleScript()
guinness Posted January 3, 2012 Posted January 3, 2012 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 parsing • AutoIt Search • AutoIt3 Portable • AutoIt3WrapperToPragma • AutoItWinGetTitle()/AutoItWinSetTitle() • Coding • DirToHTML5 • FileInstallr • FileReadLastChars() • GeoIP database • GUI - Only Close Button • GUI Examples • GUICtrlDeleteImage() • GUICtrlGetBkColor() • GUICtrlGetStyle() • GUIEvents • GUIGetBkColor() • Int_Parse() & Int_TryParse() • IsISBN() • LockFile() • Mapping CtrlIDs • OOP in AutoIt • ParseHeadersToSciTE() • PasswordValid • PasteBin • Posts Per Day • PreExpand • Protect Globals • Queue() • Resource Update • ResourcesEx • SciTE Jump • Settings INI • SHELLHOOK • Shunting-Yard • Signature Creator • Stack() • Stopwatch() • StringAddLF()/StringStripLF() • StringEOLToCRLF() • VSCROLL • WM_COPYDATA • More Examples... Updated: 22/04/2018
emendelson Posted January 3, 2012 Author Posted January 3, 2012 You'd want to use something like this: If $list[$i][0] = @ScriptName Then Rather than $list[$i][1]. Aha! Thank you!
emendelson Posted January 3, 2012 Author Posted January 3, 2012 (edited) 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 January 3, 2012 by emendelson
BattleVena Posted November 6, 2013 Posted November 6, 2013 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.
Carlo84 Posted November 7, 2013 Posted November 7, 2013 (edited) 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 November 7, 2013 by Djarlo _SplashProgressImage | _Regionselector | _IsPressed360 | _UserAccountContol_SetLevel | _ListSubFolders
BattleVena Posted November 7, 2013 Posted November 7, 2013 (edited) 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 November 7, 2013 by BattleVena
Carlo84 Posted November 7, 2013 Posted November 7, 2013 (edited) 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 November 7, 2013 by Djarlo _SplashProgressImage | _Regionselector | _IsPressed360 | _UserAccountContol_SetLevel | _ListSubFolders
BattleVena Posted November 7, 2013 Posted November 7, 2013 (edited) 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 November 7, 2013 by BattleVena
Exit Posted November 7, 2013 Posted November 7, 2013 (edited) 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 November 7, 2013 by Exit App: Au3toCmd UDF: _SingleScript()
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now