mit einem Mutex zu verhindern, portiert zu PureBasic.
Dabei kann man über Flags festlegen, ob man eine Instanz auf dem ganzen System oder für
jeden Systembenutzer oder auf jedem Desktop im System zulassen möchte.
Der ausführliche Artikel von Dr. Joseph M. Newcomer dazu:
- Avoiding Multiple Instances of an Application (auf seiner Homepage)
- Avoiding Multiple Instances of an Application (bei codeproject)
Code: Alles auswählen
;
; 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...")
eigenen, universellen GUID, so dass keine doppelten Namen auftreten können.
Eine eigene GUID kann man mit folgendem Code erstellen:
Code: Alles auswählen
;
; 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()