Single Instance Application

Share your advanced PureBasic knowledge/code with the community.
Psych
Enthusiast
Enthusiast
Posts: 239
Joined: Thu Dec 18, 2008 3:35 pm
Location: Wales, UK

Single Instance Application

Post by Psych »

Much discussion has been had as to what is the best, most efficient way to create a single instance application.
The most common solution being the creation of a 'named mutex', however this method doesn't provide any functionality to inform the original application that an instance was attempted.
This little procedure (windows only) not only tests if the same program in running, it will also post a message to that programs message queue informing the application that another instance was started.
Very useful for tray apps where the program will appear from the tray if the user double clicks the program icon on the desktop.

Code:

Code: Select all

Procedure CheckAndPost(uniquename$,wmessage=#WM_APP,autopost=1)
	Protected fn$="Global\"+uniquename$,tmp
	RtlAdjustPrivilege_(30,1,0,@tmp)
	Protected fm=CreateFileMapping_(#INVALID_HANDLE_VALUE,#Null,#PAGE_READWRITE|#SEC_COMMIT,0,4,@fn$)
	If fm
		tmp=GetLastError_()
		Protected *vm=MapViewOfFile_(fm,#FILE_MAP_ALL_ACCESS,0,0,4)
		If *vm
			If tmp=#ERROR_ALREADY_EXISTS
				tmp=PeekL(*vm)
				If autopost
					PostThreadMessage_(tmp,wmessage,-1,-1)
				EndIf
				ProcedureReturn tmp
			Else
				PokeL(*vm,GetCurrentThreadId_())
			EndIf
		EndIf
	EndIf
EndProcedure
Usage:

Code: Select all

If CheckAndPost("my app name")
	End
EndIf
Global WINSTYLE=#PB_Window_ScreenCentered|#PB_Window_SystemMenu
If Not OpenWindow(1,#PB_Ignore,#PB_Ignore,300,300,"Single Instance",WINSTYLE)
	End
EndIf
Repeat
	Select WaitWindowEvent(10)
		Case #PB_Event_CloseWindow
			Break
		Case #WM_APP
			If EventlParam()=-1 And EventwParam()=-1
				MessageRequester("Single Instance","running")
			EndIf
	EndSelect
ForEver
You must supply an unique name to the procedure, as it is used in the creation of the shared memory.
The wmessage parameter is the message that will be posted to the running application, it defaults to #WM_APP but I prefer to create my own unique message using RegisterWindowsMessage() with the same unique string I pass to this procedure plus "_running", this way I only need check for that in the message loop (lparam and wparam are not needed).
autopost is self explanatory, put a 0 here and the routine wont post the message to the application.
The function will return 0 (not running) or the threadID of the running program, handy if you want to post more messages, etc.
Hope you like.
PS. I didn't check the forums before posting this, so if I've duplicated an existing method, appologies.
----------------------------------------------------------------------------
Commenting your own code is admitting you don't understand it.
----------------------------------------------------------------------------
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Single Instance Application

Post by IdeasVacuum »

....very practical solution, thanks for sharing Psych 8)
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5494
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: Single Instance Application

Post by Kwai chang caine »

Works fine
Thanks for sharing 8)
ImageThe happiness is a road...
Not a destination
User avatar
jacdelad
Addict
Addict
Posts: 1992
Joined: Wed Feb 03, 2021 12:46 pm
Location: Riesa

Re: Single Instance Application

Post by jacdelad »

I tried this code with 6.10, but it does...nothing. Does anyone know why? I'm not firm with filemappings.
Good morning, that's a nice tnetennba!

PureBasic 6.21/Windows 11 x64/Ryzen 7900X/32GB RAM/3TB SSD
Synology DS1821+/DX517, 130.9TB+50.8TB+2TB SSD
User avatar
idle
Always Here
Always Here
Posts: 5836
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Single Instance Application

Post by idle »

User avatar
jacdelad
Addict
Addict
Posts: 1992
Joined: Wed Feb 03, 2021 12:46 pm
Location: Riesa

Re: Single Instance Application

Post by jacdelad »

Ah thanks, unfortunately my shift is over now and I'm not allowed to work for four days. :cry:

Happy Easter everyone!
Good morning, that's a nice tnetennba!

PureBasic 6.21/Windows 11 x64/Ryzen 7900X/32GB RAM/3TB SSD
Synology DS1821+/DX517, 130.9TB+50.8TB+2TB SSD
Quin
Addict
Addict
Posts: 1125
Joined: Thu Mar 31, 2022 7:03 pm
Location: Colorado, United States
Contact:

Re: Single Instance Application

Post by Quin »

I made a tiny module to do this that fully works for me on Windows 10 with PB 6.10 -> https://www.purebasic.fr/english/viewtopic.php?t=83926
Post Reply