ported to PureBasic.
By using this way, you can define (with flags) what "one instance of an application" actually means,
for example one instance on the whole system, one instance for every user, or one instance for
every desktop on the system.
The Article by Dr. Joseph M. Newcomer:
- Avoiding Multiple Instances of an Application (his homepage)
- Avoiding Multiple Instances of an Application (at codeproject)
Code: Select all
;
; Avoiding Multiple Instances of an Application
;
; by Dr. Joseph M. Newcomer
;
; - http://www.flounder.com/nomultiples.htm
; - http://www.codeproject.com/Articles/538/Avoiding-Multiple-Instances-of-an-Application
;
; PB port by Danilo, April 2012
;
;
; SI_SESSION_UNIQUE - Allow one instance per login session
; SI_DESKTOP_UNIQUE - Allow one instance per desktop
; SI_TRUSTEE_UNIQUE - Allow one instance per user account
; SI_SESSION_UNIQUE | SI_DESKTOP_UNIQUE - Allow one instance per login session,
; instances in different login sessions
; must also reside on a different desktop
; SI_TRUSTEE_UNIQUE | SI_DESKTOP_UNIQUE - Allow one instance per user account,
; instances in login sessions running a
; different user account must also reside
; on different desktops.
; SI_SYSTEM_UNIQUE - Allow only one instance on the whole system
;
;
#SI_SESSION_UNIQUE = $0001 ; Allow only one instance per login session
#SI_DESKTOP_UNIQUE = $0002 ; Allow only one instance on current desktop
#SI_TRUSTEE_UNIQUE = $0004 ; Allow only one instance for current user
#SI_SYSTEM_UNIQUE = $0000 ; Allow only one instance at all (on the whole system)
Procedure.s CreateUniqueName( name.s, mode.l = #SI_DESKTOP_UNIQUE )
Protected output.s = "Global\"+name
If mode & #SI_DESKTOP_UNIQUE
Protected hDesk.i, cchDesk.l, userinfo.s
output + "-"
hDesk = GetThreadDesktop_( GetCurrentThreadId_() )
cchDesk = #MAX_PATH - Len(name) - 1
userinfo = Space(#MAX_PATH)
If GetUserObjectInformation_( hDesk, #UOI_NAME, @name, cchDesk, @cchDesk )
output + Trim(name)
Else
output + "Win9x"
EndIf
EndIf
If mode & #SI_SESSION_UNIQUE
Protected hToken.i, cbBytes.l, *pTS
If OpenProcessToken_( GetCurrentProcess_(), #TOKEN_QUERY, @hToken )
If GetTokenInformation_( hToken, #TokenStatistics, #Null, cbBytes, @cbBytes )=0 And GetLastError_() = #ERROR_INSUFFICIENT_BUFFER
*pTS = AllocateMemory( cbBytes )
If *pTS
If GetTokenInformation_( hToken, #TokenStatistics, *pTS, cbBytes, @cbBytes )
output + "-" + RSet(Hex(PeekQ(*pts+8),#PB_Quad),16,"0")
EndIf
FreeMemory(*pTS)
EndIf
EndIf
EndIf
EndIf
If mode & #SI_TRUSTEE_UNIQUE
Protected user.s , cchUser.l = 64
Protected domain.s, cchDomain = 64
user = Space(cchUser)
domain = Space(cchDomain)
If GetUserName_( @user, @cchUser )
output + "-" + Trim(user)
EndIf
cchDomain = GetEnvironmentVariable_( "USERDOMAIN", @domain, cchDomain )
output + "-" + Trim(domain)
EndIf
ProcedureReturn Left(output,#MAX_PATH)
EndProcedure
Procedure IsInstancePresent( name.s , mode.l = #SI_DESKTOP_UNIQUE )
Protected err, uniqueName.s
Static hMutex = #Null
If hMutex = #Null
uniqueName = CreateUniqueName( name, mode )
hMutex = CreateMutex_( #Null, #False, @uniqueName )
err = GetLastError_()
If err = #ERROR_ALREADY_EXISTS : ProcedureReturn #True : EndIf
If err = #ERROR_ACCESS_DENIED : ProcedureReturn #True : EndIf
EndIf
ProcedureReturn #False
EndProcedure
;------------------------------------------------------------------------------------------------
#APPGUID = "{B883B6AB-AE6C-4ADC-AA13-5B3D0195AD5F}"
; Debug CreateUniqueName(#APPGUID, #SI_SESSION_UNIQUE )
; Debug CreateUniqueName(#APPGUID, #SI_DESKTOP_UNIQUE )
; Debug CreateUniqueName(#APPGUID, #SI_TRUSTEE_UNIQUE )
; Debug CreateUniqueName(#APPGUID, #SI_SYSTEM_UNIQUE )
;
; Debug CreateUniqueName(#APPGUID, #SI_SESSION_UNIQUE | #SI_DESKTOP_UNIQUE )
; Debug CreateUniqueName(#APPGUID, #SI_TRUSTEE_UNIQUE | #SI_DESKTOP_UNIQUE )
If IsInstancePresent(#APPGUID, #SI_SYSTEM_UNIQUE )
End ; already running
EndIf
;
; start of program
;
MessageRequester("Info","Program running...")
Make your own unique GUID by using the following code:
Code: Select all
;
; by ts-soft and Flype
;
; http://www.purebasic.fr/english/viewtopic.php?f=5&t=23233&start=11
;
Procedure.s MakeGUID()
Protected guid.GUID, lpsz.s{78}
If CoCreateGuid_(@guid) = #S_OK
ProcedureReturn PeekS(@lpsz, StringFromGUID2_(guid, @lpsz, 78), #PB_Unicode)
EndIf
EndProcedure
Debug MakeGUID()