Akshay07 Posted January 13, 2010 Posted January 13, 2010 Hi all, Here is what I would like to do: #include <Misc.au3> if _Singleton("MyScript",1) = 0 Then $answer = Msgbox(1,"Warning","An occurence of MyScript is already running. Click OK to kill it or CANCEL to exit.") If $answer = 2 Then ; CANCEL Exit Else ; OK ; KILL EXISTING PREVIOUS INSTANCE OF MyScript EndIf EndIf Msgbox(0,"OK","Only one occurence of MyScript is running") How can I do the "KILL EXISTING PREVIOUS INSTANCE OF MyScript" part? Thank you.
Developers Jos Posted January 13, 2010 Developers Posted January 13, 2010 (edited) I think ProcessClose(@ScriptName) would work.Questions I have reading this are:- how would it know which to kill when the exe names are the same?- this will kill the wrong one when the EXE has another name.. right?JOs Edited January 13, 2010 by Jos SciTE4AutoIt3 Full installer Download page - Beta files Read before posting How to post scriptsource Forum etiquette Forum Rules Live for the present, Dream of the future, Learn from the past.
trancexx Posted January 13, 2010 Posted January 13, 2010 As Jos said it's not that simple. Can be done like this: #include <Misc.au3> If _Singleton("MyScript", 1) = 0 Then $answer = MsgBox(1, "Warning", "An occurence of MyScript is already running. Click OK to kill it or CANCEL to exit.") If $answer = 2 Then ; CANCEL Exit Else ; OK ; KILL EXISTING PREVIOUS INSTANCE OF MyScript $aProc = ProcessList(StringRegExpReplace(@AutoItExe, ".*\\", "")) For $i = 0 To UBound($aProc) - 1 If $aProc[$i][1] <> @AutoItPID Then ProcessClose($aProc[$i][1]) Next EndIf EndIf MsgBox(0, "OK", "Only one occurence of MyScript is running") But still it's not totally right (that first line in Jos's response). It can (should) be done in much more advanced way. ♡♡♡ . eMyvnE
bogQ Posted January 14, 2010 Posted January 14, 2010 (edited) Can this help or im missing the point of this topic #include <Process.au3> If WinExists("autoit win") Then ProcessClose(WinGetProcess("autoit win")) AutoItWinSetTitle("autoit win") While 1 WEnd Edited January 14, 2010 by bogQ TCP server and client - Learning about TCP servers and clients connectionAu3 oIrrlicht - Irrlicht projectAu3impact - Another 3D DLL game engine for autoit. (3impact 3Drad related) There are those that believe that the perfect heist lies in the preparation.Some say that it’s all in the timing, seizing the right opportunity. Others even say it’s the ability to leave no trace behind, be a ghost.
KaFu Posted January 14, 2010 Posted January 14, 2010 I had problems with _Singleton() on my Notebook and wrote an alternate version of "Enforce Single Instance of Program". In the second posting in that thread I show how to pass a commandline parameter to the parent instance before exiting. I think this example could be easily rewritten to pass an Exit() command to the parent script via WM_COPYDATA so it closes itself. OS: Win10-22H2 - 64bit - German, AutoIt Version: 3.3.16.1, AutoIt Editor: SciTE, Website: https://funk.eu AMT - Auto-Movie-Thumbnailer (2024-Oct-13) BIC - Batch-Image-Cropper (2023-Apr-01) COP - Color Picker (2009-May-21) DCS - Dynamic Cursor Selector (2024-Oct-13) HMW - Hide my Windows (2024-Oct-19) HRC - HotKey Resolution Changer (2012-May-16) ICU - Icon Configuration Utility (2018-Sep-16) SMF - Search my Files (2024-Oct-20) - THE file info and duplicates search tool SSD - Set Sound Device (2017-Sep-16)
Akshay07 Posted January 14, 2010 Author Posted January 14, 2010 (edited) Thanks guys. KaFu, I am afraid your script is too advanced for me, I don't fully understand it The scenario would be that there are two instances of MyScript.exe running, the names would be exactly the same. What about this (very inspired by what trancexxx proposed): #include <Misc.au3> If _Singleton("MyScript", 1) = 0 Then $answer = MsgBox(1, "Warning", "An occurence of MyScript is already running. Click OK to kill it or CANCEL to exit.") If $answer = 2 Then ; CANCEL Exit Else ; OK ; KILL EXISTING PREVIOUS INSTANCE OF MyScript $aProc = ProcessList ( "MyScript.exe" ) For $i = 1 To $aProc[0][0] If $aProc[$i][1] <> @AutoItPID Then ProcessClose($aProc[$i][1]) Next EndIf EndIf MsgBox(0, "OK", "Only one occurence of MyScript is running") Edit: I just tested this and it seems to work fine. I had 3 instances of MyScript.exe running. When starting the 4th one, I clicked on OK and the previous 3 instances were killed. The only problem is that the corresponding tray icons don't disappear. They do if I move the mouse over these icons (without clicking). I will create another topic for this issue to avoid mixing questions. Edited January 14, 2010 by Akshay07
KaFu Posted January 14, 2010 Posted January 14, 2010 In the func WM_COPYDATA() either exit the hard way (commented) or set a var to exit in main loop. expandcollapse popup#cs ---------------------------------------------------------------------------- AutoIt Version: 3.3.2.0 Author: myName Script Function: Template AutoIt script. #ce ---------------------------------------------------------------------------- ; Script Start - Add your code below here #NoTrayIcon #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> $bExit = False $hwnd_AutoIt = _EnforceSingleInstance('e15ff08b-84ac-472a-89bf-5f92db683165') ; any 'unique' string; created with http://www.guidgen.com/Index.aspx Opt("TrayIconHide", 1) $hGUI = GUICreate("My GUI " & $hwnd_AutoIt,300,300,Default,Default) ; will create a dialog box that when displayed is centered $label = GUICtrlCreateLabel($CmdLineRaw,10,10,300,100) GUISetState(@SW_SHOW) ; will display an empty dialog box ControlSetText($hwnd_AutoIt,'',ControlGetHandle($hwnd_AutoIt,'','Edit1'),$hGUI) ; to pass hWnd of main GUI to AutoIt default GUI GUIRegisterMsg($WM_COPYDATA, "WM_COPYDATA") While 1 sleep(10) $msg = GUIGetMsg() If $msg = $GUI_EVENT_CLOSE Then ExitLoop if $bExit = true then ExitLoop WEnd GUIDelete() Func _EnforceSingleInstance($GUID_Program = "") If $GUID_Program = "" Then Return $hwnd = WinGetHandle($GUID_Program) If IsHWnd($hwnd) Then $hwnd_Target = ControlGetText($hwnd,'',ControlGetHandle($hwnd,'','Edit1')) WM_COPYDATA_SendData(HWnd($hwnd_Target), "Exit") EndIf AutoItWinSetTitle($GUID_Program) Return WinGetHandle($GUID_Program) EndFunc ;==>_EnforceSingleInstance Func WM_COPYDATA($hWnd, $MsgID, $wParam, $lParam) ; http://www.autoitscript.com/forum/index.php?showtopic=105861&view=findpost&p=747887 ; Melba23, based on code from Yashied Local $tCOPYDATA = DllStructCreate("dword;dword;ptr", $lParam) Local $tMsg = DllStructCreate("char[" & DllStructGetData($tCOPYDATA, 2) & "]", DllStructGetData($tCOPYDATA, 3)) if StringInStr(DllStructGetData($tMsg, 1),"Exit") then ; Exit ; a) the hard way :) $bExit = true ; b) set var to exit in main loop endif EndFunc ;==>WM_COPYDATA Func WM_COPYDATA_SendData($hWnd, $sData) If Not IsHWnd($hWnd) Then Return 0 if $sData = "" then $sData = " " Local $tCOPYDATA, $tMsg $tMsg = DllStructCreate("char[" & StringLen($sData) + 1 & "]") DllStructSetData($tMsg, 1, $sData) $tCOPYDATA = DllStructCreate("dword;dword;ptr") DllStructSetData($tCOPYDATA, 2, StringLen($sData) + 1) DllStructSetData($tCOPYDATA, 3, DllStructGetPtr($tMsg)) $Ret = DllCall("user32.dll", "lparam", "SendMessage", "hwnd", $hWnd, "int", $WM_COPYDATA, "wparam", 0, "lparam", DllStructGetPtr($tCOPYDATA)) If (@error) Or ($Ret[0] = -1) Then Return 0 Return 1 EndFunc ;==>WM_COPYDATA_SendData OS: Win10-22H2 - 64bit - German, AutoIt Version: 3.3.16.1, AutoIt Editor: SciTE, Website: https://funk.eu AMT - Auto-Movie-Thumbnailer (2024-Oct-13) BIC - Batch-Image-Cropper (2023-Apr-01) COP - Color Picker (2009-May-21) DCS - Dynamic Cursor Selector (2024-Oct-13) HMW - Hide my Windows (2024-Oct-19) HRC - HotKey Resolution Changer (2012-May-16) ICU - Icon Configuration Utility (2018-Sep-16) SMF - Search my Files (2024-Oct-20) - THE file info and duplicates search tool SSD - Set Sound Device (2017-Sep-16)
ProgAndy Posted January 14, 2010 Posted January 14, 2010 It would be easier to use AutoItWinSetTitle and WinExists to create this singleton behaviour: Global Const $_SingleTonKey = "ac38f004-f30d-401c-8627-8a6ad1c2e763" ; e.g. GUID If WinExists($_SingleTonKey) Then Switch MsgBox(4, 'Instance already running', 'Kill old instance?') Case 6 $iPID = WinGetProcess($_SingleTonKey) WinKill($_SingleTonKey) Sleep(500) ProcessWaitClose($iPID, 500) ProcessClose($iPID) ; only we are running now Case Else Exit ;the other Instance will continue EndSwitch EndIf AutoItWinSetTitle($_SingleTonKey) ; Script will be here *GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes
Akshay07 Posted January 14, 2010 Author Posted January 14, 2010 (edited) Thanks, I did not know that it was possible to give a window title to the script. I looked at the help for AutoItWinSetTitle and now I understand how it works. I have two questions: 1/ For my knowledge, how do you come up with "ac38f004-f30d-401c-8627-8a6ad1c2e763" ? Does it mean something or is is a random sequence to identify the window title? 2/ ProcessWaitClose($iPID, 500) ProcessClose($iPID) Why using ProcessWaitClose, then ProcessClose for the same PID? Isn't ProcessWaitClose good enough? Edited January 14, 2010 by Akshay07
ProgAndy Posted January 14, 2010 Posted January 14, 2010 Well, I added a timeout to ProcessWaitClose. It waits 500 milliseconds for the normal AutoIt-Exit (initiated by WinKill), then the process is killed with Processclose if it did not exit yet.The String I used for $_SingleTonKey is a GUID to ensure it is unique For example, use guidgen.com to create a GUID. *GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes
Akshay07 Posted January 14, 2010 Author Posted January 14, 2010 The String I used for $_SingleTonKey is a GUID to ensure it is unique For example, use guidgen.com to create a GUID.Awesome! That's very interesting piece of info! Thanks a lot
ProgAndy Posted January 14, 2010 Posted January 14, 2010 (edited) Oh, sorry, the Timeout for ProcessWaitClose is in seconds, so change to: ProcessWaitClose($iPID, 1) Edited January 14, 2010 by ProgAndy *GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes
KaFu Posted January 14, 2010 Posted January 14, 2010 It would be easier to use AutoItWinSetTitle and WinExists to create this singleton behaviour:True, but my example will exit the program gracefully, e.g. it will remove it's icon from the tray as OP asked in second thread . Remove #NoTrayIcon and Opt("TrayIconHide", 1) from the example I provided. OS: Win10-22H2 - 64bit - German, AutoIt Version: 3.3.16.1, AutoIt Editor: SciTE, Website: https://funk.eu AMT - Auto-Movie-Thumbnailer (2024-Oct-13) BIC - Batch-Image-Cropper (2023-Apr-01) COP - Color Picker (2009-May-21) DCS - Dynamic Cursor Selector (2024-Oct-13) HMW - Hide my Windows (2024-Oct-19) HRC - HotKey Resolution Changer (2012-May-16) ICU - Icon Configuration Utility (2018-Sep-16) SMF - Search my Files (2024-Oct-20) - THE file info and duplicates search tool SSD - Set Sound Device (2017-Sep-16)
ProgAndy Posted January 14, 2010 Posted January 14, 2010 True, but my example will exit the program gracefully, e.g. it will remove it's icon from the tray as OP asked in second thread . Remove #NoTrayIcon and Opt("TrayIconHide", 1) from the example I provided.Using WinKill allows that, too. To give AutoIt more time to exit properly, you can increase the timrout in ProcessWaitClose or remove ProcessClose completely *GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes
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