Page 1 of 1

How to check if a instance is already running?

Posted: 28 Feb 2017, 20:17
by A random guy
I want to check if a instance of the script is already running. If one is, then i would goto somewhere in the script then close the second instance so only one instance is running.

Re: How to check if a instance is already running?

Posted: 28 Feb 2017, 20:42
by coolykoen
if you want it to just make sure there is never more than one instance of the script running, all you have to do is place this at the top of your script:

Code: Select all

#SingleInstance, Ignore
That tells the script to check wether it's already running, and if it is, closes itself.

Re: How to check if a instance is already running?

Posted: 28 Feb 2017, 22:08
by A random guy
no i want it so if one instance is already running then i want the script to have a subroutine

Re: How to check if a instance is already running?

Posted: 28 Feb 2017, 22:56
by Masonjar13
You would set #singleInstance off to allow a second instance to run, then you would have it check for an already running instance of it. There are several ways to check if another instance is running, depending on if it's compiled or not. A Google search will help you with that. Then, if another instance is found, you may use SendMessage/PostMessage to give the other instance data. You could also write to a file to transfer data.

Alternatively, you could set #singleInstance force, specifying an onExit routine. This may create an error in the newer instance in the form of it being "stuck" between running and waiting for the other instance to close, however (untested).

Re: How to check if a instance is already running?

Posted: 28 Feb 2017, 23:43
by wolf_II
Search for mutex. Here is an example that I wrote for myself after reading the topics:

Code: Select all

#NoEnv
#SingleInstance, Off
SetWorkingDir, %A_ScriptDir%
MutexName := "qwerty"

    ;-----------------------------------
    ; check named mutex object
    ;-----------------------------------
    If DllCall("OpenMutex", Int, 0x100000, Int,NULL, Str,MutexName)
        Gosub, AlreadyRunning


    ;-----------------------------------
    ; create named mutex object
    ;-----------------------------------
    hMutex := DllCall("CreateMutex", Int,NULL, Int,False, Str,MutexName)


    ;-----------------------------------
    ; use a GUI to keep script running
    ;-----------------------------------
    Gui, Margin, 100, 60
    Gui, Add, Text,, %hMutex%
    Gui, Show,, Mutex

Return



;-------------------------------------------------------------------------------
GuiClose: ; clean up
;-------------------------------------------------------------------------------
    DllCall("ReleaseMutex", Ptr,hMutex)

ExitApp



;-------------------------------------------------------------------------------
AlreadyRunning: ; no return from here
;-------------------------------------------------------------------------------
    Msgbox,,, Already running, 1

ExitApp


Re: How to check if a instance is already running?

Posted: 01 Mar 2017, 18:01
by A random guy
Can this work. It's just a example

Code: Select all

#NoEnv
#SingleInstance, Off
SetWorkingDir, %A_ScriptDir%
MutexName := "qwerty"

    ;-----------------------------------
    ; check named mutex object
    ;-----------------------------------
    If DllCall("OpenMutex", Int, 0x100000, Int,NULL, Str,MutexName)
        Gosub, AlreadyRunning


    ;-----------------------------------
    ; create named mutex object
    ;-----------------------------------
    hMutex := DllCall("CreateMutex", Int,NULL, Int,False, Str,MutexName)

Start:
   
    sendinput l
Return

Goto Start



;-------------------------------------------------------------------------------
AlreadyRunning: ; no return from here
;-------------------------------------------------------------------------------
    Msgbox,,, Already running, 1

ExitApp

Re: How to check if a instance is already running?

Posted: 02 Mar 2017, 09:09
by wolf_II
I don't think this would work as intended. What do you want to do?

Re: How to check if a instance is already running?

Posted: 02 Mar 2017, 21:27
by A random guy
OK so i tested using your script but the variable doesn't change when opening the second instance. Here is the script in its basic form

Code: Select all

Unlocked = 1
MutexName := "qwerty"

If DllCall("OpenMutex", Int, 0x100000, Int,NULL, Str,MutexName)
        Gosub, AlreadyRunning

hMutex := DllCall("CreateMutex", Int,NULL, Int,False, Str,MutexName)

Loop {
Sleep, 100000
If Unlocked = 1
{
Msgbox, 4414, Locked, Locked
}
}


AlreadyRunning
MsgBox, 4, Locked!, Do you want to unlock it?
IfMsgBox Yes
Unlocked := 0,
ExitApp

Re: How to check if a instance is already running?  Topic is solved

Posted: 03 Mar 2017, 02:06
by wolf_II
Where do you plan to release the mutex? Are you quite sure it is safe to ignore that?
Why would the variable change, when you run a second instance of your script? The variable you mean is Unlocked, right?

Instance #1: starts, sets Unlocked to 1 and gets caught in an endless loop.
Instance #2: starts, sets its own Unlocked to 1 as well, branches off to a subroutine (as per your original request), puts up a MsgBox and exits.

Where did you expect a variable to change? I guess you want to send data from Instance #2 back to Instance #1?
In that case, you need to write code to send data from the second instance back to the first, it won't happen otherwise.

There are many ways to send data between two scripts, including two instances of the same script.
Look at this thread: https://autohotkey.com/boards/viewtopic ... 360#p85360. There are several suitable suggestions.

Re: How to check if a instance is already running?

Posted: 03 Mar 2017, 03:18
by wolf_II
I wrote an example which sends random data from any additional instance back to the first instance.
Random data are the two numbers 555 and 789.

Code: Select all

#NoTrayIcon
#SingleInstance, Off
MutexName := "random"

    If DllCall("OpenMutex", Int, 0x100000, Int, 0, Str, MutexName)
        Gosub, AlreadyRunning

    Menu, Tray, Icon ; show
    hMutex := DllCall("CreateMutex", Int, 0, Int, False, Str, MutexName)
    OnMessage(0x5678, "Receiver")
    OnExit, ReleaseMutex

Return



;-------------------------------------------------------------------------------
ReleaseMutex: ; clean up
;-------------------------------------------------------------------------------
    DllCall("ReleaseMutex", Ptr, hMutex)

ExitApp



;-------------------------------------------------------------------------------
Receiver(wParam, lParam) { ; handle incoming messages from additional instances
;-------------------------------------------------------------------------------
    MsgBox,, Receiver, wParam: %wParam%`nlParam: %lParam%
}



;-------------------------------------------------------------------------------
AlreadyRunning: ; additional instances run this subroutine
;-------------------------------------------------------------------------------
    DetectHiddenWindows, On
    WinGet, hwnd, List, %A_ScriptFullPath% ahk_class AutoHotkey
    Loop, %hwnd%
        If (hwnd%A_Index% != A_ScriptHwnd)
            ; send random data to first instance
            PostMessage, 0x5678, 555, 789,, % "ahk_id " hwnd%A_Index%

ExitApp ; no return from here
In this example I use a MsgBox as an indicator. This is bad for the following reason:
When you start the script a third time while the "MsgBox from the second" is still displayed, the message from the third script is lost.

Re: How to check if a instance is already running?

Posted: 03 Mar 2017, 11:29
by brutus_skywalker
I dunno why you want it,but i find '#SingleInstance force' doesn't provide foolproof reliablity as i have noticed, so here...

Code: Select all

selfInstanceCheck()

MsgBox, Instance running

ExitApp


selfInstanceCheck() {
;self instance check routine
#SingleInstance, off	;for any of the following below to be usefull you need to disable multiple instance prompts by ahk

;check previous instance
FileReadLine, pidFromFile, pidCheckFile, 1
MsgBox, %pidFromFile%
Process, Exist, %pidFromFile%
if (ErrorLevel != 0)	;process with PID in file(previous instace) does exist, so exit
	ExitApp

;no other instance so put own pid into file
Process, Exist
instancePID := ErrorLevel
FileDelete, pidCheckFile	;simple reset
FileAppend, %instancePID%, pidCheckFile	;place pid of  currently running process in a file
}

and for instace checking of other processes...

Code: Select all


MsgBox, % processInstances_check("svchost.exe")
processInstances_check(targetProc)
{
count = 0
For process in ComObjGet("winmgmts:").ExecQuery("Select *from Win32_Process")
	If (process.name = targetProc)
		count++
Return, count
}


Re: How to check if a instance is already running?

Posted: 11 Mar 2017, 19:53
by A random guy
wolf_II wrote: Where did you expect a variable to change? I guess you want to send data from Instance #2 back to Instance #1?
In that case, you need to write code to send data from the second instance back to the first, it won't happen otherwise.

There are many ways to send data between two scripts, including two instances of the same script.
Look at this thread: https://autohotkey.com/boards/viewtopic ... 360#p85360. There are several suitable suggestions.
Thanks Man. Got it to work :superhappy: