Page 1 of 1
[Solved] CreateMutex allowing multiple instances
Posted: Mon Nov 11, 2019 10:06 am
by BarryG
I've got this code near the start of my source:
Code: Select all
Global appmutex=CreateMutex_(0,1,"My_App_Unique_ID")
MessageRequester("RunOnce","Mutex: "+Str(appmutex))
But when I compile it to an exe and run several instances of it, the "appmutex" variable is always non-zero, meaning the mutex was successfully created for each instance (see screenshot).
However,
it's not supposed to, and
it should return 0 in the MessageRequester() when a match for the mutex name is already found. Same if I use a semaphore.
This used to work before to prevent multiple instances of my app (only run once), but not anymore. Using Windows 10 Pro, with both 32-bit and 64-bit of PureBasic 5.71. Any ideas?
Re: CreateMutex allowing multiple instances
Posted: Mon Nov 11, 2019 11:49 am
by Marc56us
Forgot to test the return error?
GetLastError_()=#ERROR_ALREADY_EXISTS
Code: Select all
; Determine if only one instance is running
; https://rosettacode.org/wiki/Determine_if_only_one_instance_is_running#PureBasic
;
#MyApp="MyLittleApp"
Mutex=CreateMutex_(0,1,#MyApp)
If GetLastError_()=#ERROR_ALREADY_EXISTS
MessageRequester(#MyApp,"One instance is already started.")
End
EndIf
; Main code executes here
ReleaseMutex_(Mutex)
End
Source:
https://rosettacode.org/wiki/Determine_ ... #PureBasic
Windows 10 x64 family: OK
(Not tested elsewhere)

Re: CreateMutex allowing multiple instances
Posted: Mon Nov 11, 2019 12:43 pm
by BarryG
Solved. It was nothing to do with GetLastError_(), which yes, I was also checking but didn't show in my example. Here's how it was solved: my app, when detecting the existing mutex, was sending a #HWND_BROADCAST message to the first instance. However, since it was being done with SendMessage_(), the second instance wasn't returning to quit itself with "End". I simply changed SendMessage_() to PostMessage_() and it now works again.
Re: [Solved] CreateMutex allowing multiple instances
Posted: Thu Jan 22, 2026 4:49 pm
by Michael Vogel
I'm using a code similar to Marc's example for many times but now I'd like to add a simple restart function to the program which could be useful in certain situation (e.g. DPI settings change)...
Without a delay the mutex seems to be still present, a fixed delay would work but is not elegante.
So I thought doing a loop trying to create a mutex until it works or timeout is reached. But I am wrong, the last error stays frozen - so what is wrong here?
Code: Select all
Procedure Main(); Needs to be compiled to MyApp.exe
Protected s.s
n=Bool(ProgramParameter(0)=".")*16; Waits up to 1.5 seconds to see if no mutex is present...
If n
;Delay(1000); /// would work then
EndIf
Repeat
mutti=CreateMutex_(0,0,@"MyApp")
m=Bool(GetLastError_()=#ERROR_ALREADY_EXISTS)
s+Str(mutti)+": "+Str(m)+#CR$
If m
ReleaseMutex_(mutti)
CloseHandle(mutti)
Debug GetLastError_()
n-1
Delay(100)
Debug Str(n)+", "+Str(mutti)
EndIf
Until m=0 Or n<0
MessageRequester(Str(m)+", "+Str(n),s)
If m
ReleaseMutex_(mutti)
Else
OpenWindow(0,20,20,200,200,"")
ButtonGadget(1,20,20,160,40,"Restart")
ButtonGadget(2,20,120,160,40,"Quit")
Repeat
Select WaitWindowEvent()
Case #PB_Event_Menu,#PB_Event_Gadget
quit=EventMenu()
EndSelect
Until quit
If quit=1
RunProgram("MyApp.exe",".",".")
EndIf
EndIf
EndProcedure
Main()