Making it so only one instance of a program can be opened
Making it so only one instance of a program can be opened
Ok, I'd like to know how to make it so that only one instance of a program can be opened.  The only problem is, their might be copies of the program in different paths, and I dont want them to be able to open either if one is currently running.  Any ideas?
			
			
									
									
						- 
				FloHimself
- Enthusiast 
- Posts: 229
- Joined: Wed May 14, 2003 3:38 pm
- Location: Lüneburg - Germany
another way is using a 'broadcast' message, doing a kind of ping pong action:
1. first instance starts, sends out a message 'i'm here'
2. no reply -> i'm the only one
3. second instance starts, sends out a message "i'm here'
4. first instance replies: 'no you're not'
5. second instance sees the message and knows it's time to quit
			
			
									
									1. first instance starts, sends out a message 'i'm here'
2. no reply -> i'm the only one
3. second instance starts, sends out a message "i'm here'
4. first instance replies: 'no you're not'
5. second instance sees the message and knows it's time to quit
( PB6.00 LTS Win11 x64 Asrock AB350 Pro4 Ryzen 5 3600 32GB GTX1060 6GB - upgrade incoming...)
( The path to enlightenment and the PureBasic Survival Guide right here... )
						( The path to enlightenment and the PureBasic Survival Guide right here... )
Re: Making it so only one instance of a program can be opene
> I'd like to know how to make it so that only one instance of a program
> can be opened.
Read the FAQ: viewtopic.php?t=4876
			
			
									
									
						> can be opened.
Read the FAQ: viewtopic.php?t=4876
- NoahPhense
- Addict 
- Posts: 1999
- Joined: Thu Oct 16, 2003 8:30 pm
- Location: North Florida
Re: Making it so only one instance of a program can be opene
Here's my mutex lib. It's finished, but I haven't released it yet. GoingMortamer wrote:Ok, I'd like to know how to make it so that only one instance of a program can be opened. The only problem is, their might be copies of the program in different paths, and I dont want them to be able to open either if one is currently running. Any ideas?
to release it with a few other tools that I use often. All libs will have
linked help files.
Download Here: Mutex_Lib
Just drop this in \\PureBasic\PureLibraries\UserLibraries\
How to use:
Code: Select all
; mutex example
OpenMutex("whatever")
MessageBox_(0,"Hello World!", "mutex example", 0)
CloseMutex()
End- 
				zapman*
- Enthusiast 
- Posts: 115
- Joined: Wed Jun 02, 2004 10:17 pm
- Location: New Caledonia (South Pacific)
- Contact:
A shorter solution:
			
			
									
									Code: Select all
#ProgName = "MyProgram"
;
Procedure IsLaunched (Name$)
  Handle=0
  Hwnd = FindWindow_( 0, 0 )
  While Hwnd <> 0
    Txt.s = Space(256)
    GetWindowText_(Hwnd, Txt, 256)
    Hwnd = GetWindow_(Hwnd, #GW_HWNDNEXT)
    If Left(Txt,Len(nom$)) = Name$
      Handle=Hwnd
      Hwnd=0
    EndIf
  Wend
  ProcedureReturn (Handle)
EndProcedure
;
If IsLaunched (#ProgName)
  End
EndIf
OpenWindow(0,PosX,PosY,420,280,#PB_Window_ScreenCentered,#ProgName)
....
....
Don't try - DO it !
						The simplest solution is:
If hwnd is 0 it wasn't found, if found it's the handle!
Windows only report the first window matching the name!
Then again, if two programs have the same name
there is no easy way to tell them apart, the code in the post above would have the same issue!
			
			
									
									
						Code: Select all
hwnd=FindWindow_(0,title)Windows only report the first window matching the name!
Then again, if two programs have the same name
there is no easy way to tell them apart, the code in the post above would have the same issue!
- netmaestro
- PureBasic Bullfrog 
- Posts: 8452
- Joined: Wed Jul 06, 2005 5:42 am
- Location: Fort Nelson, BC, Canada
Here is a little code snippet that works beautifully and is elegantly short. It works on the semaphore principle, where you attempt to create a semaphore when your program starts. If it exists, you end the program. The beauty of it is that the semaphore will be deleted automatically by Windows when the process that created it ends. Here is the one I use for my screensavers:
*a = CreateSemaphore_(null,0,1,"PreviewModeSemaphore")
If *a <> 0 And GetLastError_()= #ERROR_ALREADY_EXISTS
CloseHandle_(*a)
End
EndIf
			
			
													*a = CreateSemaphore_(null,0,1,"PreviewModeSemaphore")
If *a <> 0 And GetLastError_()= #ERROR_ALREADY_EXISTS
CloseHandle_(*a)
End
EndIf
					Last edited by netmaestro on Wed Feb 22, 2006 7:58 am, edited 1 time in total.
									
			
									BERESHEIT
						fixed Version of Zapmanns code 
GetWindow_(Hwnd, #GW_HWNDNEXT)
must called after the if endif construct because
the hwnd from the next Window will returned by IsLaunched
			
			
									
									
						GetWindow_(Hwnd, #GW_HWNDNEXT)
must called after the if endif construct because
the hwnd from the next Window will returned by IsLaunched
Code: Select all
Procedure.l IsLaunched(Name$) 
Hwnd = FindWindow_( 0, 0 )
While Hwnd <> 0
   Txt.s = Space(256)
   GetWindowText_(Hwnd, Txt, 256)  
   If Left(Txt,Len(Name$)) = Name$ 
      ProcedureReturn Hwnd
   EndIf
   Hwnd = GetWindow_(Hwnd, #GW_HWNDNEXT)
Wend
ProcedureReturn #False
EndProcedure
@clipper:
You shouldn't use the FindWindow() approach because it is unreliable. Take a look into the following thread:
http://www.purebasic.fr/english/viewtopic.php?t=23351
And please read about the problems with FindWindow():
http://www.developerfusion.co.uk/show/1716/5
			
			
									
									
						You shouldn't use the FindWindow() approach because it is unreliable. Take a look into the following thread:
http://www.purebasic.fr/english/viewtopic.php?t=23351
And please read about the problems with FindWindow():
http://www.developerfusion.co.uk/show/1716/5
For a long time I have been using this procedure and am very happy with it:
In my main code I set #Program$ to the name of my program before calling the Alreadyrunning() routine.
FYI the text "AKJ" (my initials) is included to reduce the probability that my semaphore name duplicates that of a semaphore already in use.
			
			
									
									Code: Select all
Procedure AlreadyRunning()
; Ensure the current program is not already running
; Terminate this process if it is
; Uses #Program$
Protected app, msg$
app=CreateSemaphore_(0,0,1,"AKJ "+#Program$)
If app<>0 And GetLastError_()=#ERROR_ALREADY_EXISTS
  CloseHandle_(app) ; This line can be omitted
  msg$="The "+#Program$+" program is already running."+#CRLF$+#CRLF$
  msg$+"This process will terminate."
  MessageRequester(#Program$+" Error", msg$, #MB_ICONERROR)
  End
EndIf 
EndProcedureFYI the text "AKJ" (my initials) is included to reduce the probability that my semaphore name duplicates that of a semaphore already in use.
Anthony Jordan
						





