Page 1 sur 1
[R] Singleton
Posté : jeu. 09 avr. 2020 14:15
par Faco
Bonjour à tous,
Un nouveau sujet sur le singleton, j'arrive pas à le faire fonctionner.
J'ai récupérer un des derniers exemples en date, celui de TLem pour faire un test qui fonctionne et, ... ba non...
viewtopic.php?p=103006#p103006
Quand je compile, je peux lancer autant de fois que je veux le programme et le singleton ne se déclenche pas.
Par contre, si je lance l'exe compilé et que j'essaie de "RUN" le script au3, là le singleton se déclenche et j'ai la MsgBox d'alerte ("
programme déjà lancé...")
Merci de votre aide.
AutoIt Version: 3.3.14.5
Windows 10 1909
Edit: Solution
viewtopic.php?p=104943#p104943
Re: [..] Singleton
Posté : jeu. 09 avr. 2020 16:02
par mikell
Tu as utilisé le script de Tlem sans rien y changer ?
Si Singleton déclenche sur le fichier .au3, ça ressemble à une utilisation de @ScriptName (qui change si compilation)
Re: [..] Singleton
Posté : jeu. 09 avr. 2020 22:41
par Tlem
Bonsoir.
J'ai ré-écrit le code du message indiqué par Faco et j'en ai profité pour rajouter un second exemple car dans le contexte des questions de Dimvar, j'avais seulement proposé un script où le nom devait être figé. Maintenant il y a les deux possibilités. ^^
@Faco : Le second script devrait mieux vous convenir.

Re: [..] Singleton
Posté : ven. 10 avr. 2020 09:32
par TommyDDR
Quand je compile, je peux lancer autant de fois que je veux le programme et le singleton ne se déclenche pas.
S'il lance le même exécutable à chaque fois, quelle que soit la façon, il aurait du avoir le message comme quoi le programme est déjà lancé.
@Faco : Le plus simple est de fournir le script, comme ça nous arrêtons d'extrapoler et nous pouvons tester

Re: [..] Singleton
Posté : ven. 10 avr. 2020 10:17
par Faco
Re,
Le script est celui de Tlem, je veux juste faire fonctionner le singleton et ensuite je rajouterai ça au début de mon/mes codes. Voici ce que je veux faire fonctionner :
#include <Misc.au3>Global $ScriptName = "TheOne"Global $ScriptVersion = "1.0.0"If _Singleton($ScriptName, 1) = 0 Then MsgBox(16, "Attention", "Impossible de lancer ce programme plus d'une fois ! Veuillez fermer l'autre occurence.") ExitEndIfMsgBox(32, @ScriptName & " " & $ScriptVersion, "Bievenue dans " & $ScriptName & " Version " & $ScriptVersion)
Je vous invite à le compiler, lancer l'exe 2 fois, puis run le code. Dans mon cas, l'exe se lance 2 fois sans déclencher le singleton alors que le run lui le déclenche.
Re: [..] Singleton
Posté : ven. 10 avr. 2020 10:34
par Tlem
Bonjour
@Faco : Comme je vous l'ai dit précédemment, utilisez l'autre version du script.
Remplacez If _Singleton($ScriptName, 1) = 0 Then
par If _Singleton(@ScriptName, 1) = 0 Then
Re: [..] Singleton
Posté : ven. 10 avr. 2020 11:04
par Faco
Bonjour,
Je veux pas vous enfoncer mais je vois pas ce que ça change, que je fixe $ScriptName ou que j'utilise la macro. Au contraire, si j'utilise
$ScriptName ="Toto"
, même si je modifie le nom de l'exe mon singleton sera toujours sur "Toto".
Mais bon, j'ai essayé et c'est la même.
#include <Misc.au3>; Test Singleton pour @ScriptNameIf _Singleton(@ScriptName, 1) = 0 Then MsgBox(16, "Attention", @ScriptName & " est déjà lancé et en cours de fonctionnement ! La fonction _Singleton() n’autorise qu'une seul instance du script.") ExitEndIfMsgBox(32, @ScriptName, "Gardez cette fenêtre ouverte et lancez le script une seconde fois pour voir le résultat de la fonction _Singleton()")
Ça fonctionne chez vous ? Quel version d'autoit pour compiler ?
Re: [..] Singleton
Posté : ven. 10 avr. 2020 11:50
par Tlem
Concernant la version d'AutoIt, c'est évidemment toujours la dernière version qui est à privilégier.
Quand au script que vous indiquez ci-dessus, il fonctionne parfaitement.
Re: [..] Singleton
Posté : ven. 10 avr. 2020 16:04
par Faco
Voila une démo, dites moi où je me trompe svp
Re: [..] Singleton
Posté : ven. 10 avr. 2020 16:48
par walkson
Bonjour,
Recompilez le code et mettre Avast en pose et ça devrait le faire

Re: [..] Singleton
Posté : ven. 10 avr. 2020 18:05
par Tlem
Un autre test : Attendez 15 secondes que Avast ai fini son scan pour lancez le programme une seconde fois.
Il y a des chances pour que Avast lance le programme compilé dans un bac à sable, du coup la détection ne peux pas fonctionner correctement.
Edit : Essayez ce code :
Code : Tout sélectionner
#include <Misc.au3>
; Test Singleton pour @ScriptName
If _Singleton2(@ScriptName, 1) = 0 Then
MsgBox(16, "Attention", @ScriptName & " est déjà lancé et en cours de fonctionnement ! La fonction _Singleton() n’autorise qu'une seul instance du script.")
Exit
EndIf
MsgBox(32, @ScriptName, "Gardez cette fenêtre ouverte et lancez le script une seconde fois pour voir le résultat de la fonction _Singleton()")
Func _Singleton2($sOccurrenceName, $iFlag = 0)
Local Const $ERROR_ALREADY_EXISTS = 183
Local Const $SECURITY_DESCRIPTOR_REVISION = 1
Local $tSecurityAttributes = 0
Local Const $hKernel32 = DllOpen('kernel32.dll')
Local $iError, $iExtended, $vReturn
Do
If BitAND($iFlag, 2) Then
; The size of SECURITY_DESCRIPTOR is 20 bytes. We just
; need a block of memory the right size, we aren't going to
; access any members directly so it's not important what
; the members are, just that the total size is correct.
Local $tSecurityDescriptor = DllStructCreate("byte;byte;word;ptr[4]")
; Initialize the security descriptor.
Local $aRet = DllCall("advapi32.dll", "bool", "InitializeSecurityDescriptor", _
"struct*", $tSecurityDescriptor, "dword", $SECURITY_DESCRIPTOR_REVISION)
If @error Then Return SetError(@error, @extended, 0)
If $aRet[0] Then
; Add the NULL DACL specifying access to everybody.
$aRet = DllCall("advapi32.dll", "bool", "SetSecurityDescriptorDacl", _
"struct*", $tSecurityDescriptor, "bool", 1, "ptr", 0, "bool", 0)
If @error Then Return SetError(@error, @extended, 0)
If $aRet[0] Then
; Create a SECURITY_ATTRIBUTES structure.
$tSecurityAttributes = DllStructCreate($tagSECURITY_ATTRIBUTES)
; Assign the members.
DllStructSetData($tSecurityAttributes, 1, DllStructGetSize($tSecurityAttributes))
DllStructSetData($tSecurityAttributes, 2, DllStructGetPtr($tSecurityDescriptor))
DllStructSetData($tSecurityAttributes, 3, 0)
EndIf
EndIf
EndIf
Local $aHandle = DllCall($hKernel32, "handle", "CreateMutexW", "struct*", $tSecurityAttributes, "bool", 1, "wstr", $sOccurrenceName)
If @error Then
$iError = @error
$iExtended = @extended
$vReturn = 0
ExitLoop
EndIf
Local $aLastError = DllCall($hKernel32, "dword", "GetLastError")
If @error Then
$iError = @error
$iExtended = @extended
$vReturn = 0
ExitLoop
EndIf
If $aLastError[0] = $ERROR_ALREADY_EXISTS Then
If BitAND($iFlag, 1) Then
DllCall($hKernel32, "bool", "CloseHandle", "handle", $aHandle[0])
If @error Then
$iError = @error
$iExtended = @extended
$vReturn = 0
ExitLoop
EndIf
$iError = $aLastError[0]
$iExtended = $aLastError[0]
$vReturn = 0
ExitLoop
Else
Exit -1
EndIf
EndIf
$vReturn = $aHandle[0]
Until 1
DllClose($hKernel32)
Return SetError($iError, $iExtended, $vReturn)
EndFunc ;==>_Singleton2
et si cela ne fonctionne toujours pas, essayez les différentes fonctions proposées dans ce message :
https://www.autoitscript.com/forum/topi ... nt=1330154
Re: [..] Singleton
Posté : ven. 10 avr. 2020 19:55
par walkson
Un autre test : Attendez 15 secondes que Avast ai fini son scan pour lancez le programme une seconde fois.
Même cela ne marche pas

Soit Avast en pose, soit lancer le programme avec sandboxie pour régler le problème.....
Le comble est que j'ai un programme qui utilise singleton et qui fonctionne très bien mais si je le recompile, le singleton ne fonctionne plus !
Après, il y a la solution barbare du codeur du dimanche (2 jours d'avance

) que je suis....
Re: [R] Singleton
Posté : sam. 11 avr. 2020 13:18
par Faco
Nickel, singleton2 marche chez moi, merci beaucoup Tlem. (Et ce n'est pas avast mais AVG et je n'est pas eu à le désactiver)
Tlem a écrit : ↑ven. 10 avr. 2020 18:05
Un autre test : Attendez 15 secondes que Avast ai fini son scan pour lancez le programme une seconde fois.
Il y a des chances pour que Avast lance le programme compilé dans un bac à sable, du coup la détection ne peux pas fonctionner correctement.
Edit : Essayez ce code :
Code : Tout sélectionner
#include <Misc.au3>
; Test Singleton pour @ScriptName
If _Singleton2(@ScriptName, 1) = 0 Then
MsgBox(16, "Attention", @ScriptName & " est déjà lancé et en cours de fonctionnement ! La fonction _Singleton() n’autorise qu'une seul instance du script.")
Exit
EndIf
MsgBox(32, @ScriptName, "Gardez cette fenêtre ouverte et lancez le script une seconde fois pour voir le résultat de la fonction _Singleton()")
Func _Singleton2($sOccurrenceName, $iFlag = 0)
Local Const $ERROR_ALREADY_EXISTS = 183
Local Const $SECURITY_DESCRIPTOR_REVISION = 1
Local $tSecurityAttributes = 0
Local Const $hKernel32 = DllOpen('kernel32.dll')
Local $iError, $iExtended, $vReturn
Do
If BitAND($iFlag, 2) Then
; The size of SECURITY_DESCRIPTOR is 20 bytes. We just
; need a block of memory the right size, we aren't going to
; access any members directly so it's not important what
; the members are, just that the total size is correct.
Local $tSecurityDescriptor = DllStructCreate("byte;byte;word;ptr[4]")
; Initialize the security descriptor.
Local $aRet = DllCall("advapi32.dll", "bool", "InitializeSecurityDescriptor", _
"struct*", $tSecurityDescriptor, "dword", $SECURITY_DESCRIPTOR_REVISION)
If @error Then Return SetError(@error, @extended, 0)
If $aRet[0] Then
; Add the NULL DACL specifying access to everybody.
$aRet = DllCall("advapi32.dll", "bool", "SetSecurityDescriptorDacl", _
"struct*", $tSecurityDescriptor, "bool", 1, "ptr", 0, "bool", 0)
If @error Then Return SetError(@error, @extended, 0)
If $aRet[0] Then
; Create a SECURITY_ATTRIBUTES structure.
$tSecurityAttributes = DllStructCreate($tagSECURITY_ATTRIBUTES)
; Assign the members.
DllStructSetData($tSecurityAttributes, 1, DllStructGetSize($tSecurityAttributes))
DllStructSetData($tSecurityAttributes, 2, DllStructGetPtr($tSecurityDescriptor))
DllStructSetData($tSecurityAttributes, 3, 0)
EndIf
EndIf
EndIf
Local $aHandle = DllCall($hKernel32, "handle", "CreateMutexW", "struct*", $tSecurityAttributes, "bool", 1, "wstr", $sOccurrenceName)
If @error Then
$iError = @error
$iExtended = @extended
$vReturn = 0
ExitLoop
EndIf
Local $aLastError = DllCall($hKernel32, "dword", "GetLastError")
If @error Then
$iError = @error
$iExtended = @extended
$vReturn = 0
ExitLoop
EndIf
If $aLastError[0] = $ERROR_ALREADY_EXISTS Then
If BitAND($iFlag, 1) Then
DllCall($hKernel32, "bool", "CloseHandle", "handle", $aHandle[0])
If @error Then
$iError = @error
$iExtended = @extended
$vReturn = 0
ExitLoop
EndIf
$iError = $aLastError[0]
$iExtended = $aLastError[0]
$vReturn = 0
ExitLoop
Else
Exit -1
EndIf
EndIf
$vReturn = $aHandle[0]
Until 1
DllClose($hKernel32)
Return SetError($iError, $iExtended, $vReturn)
EndFunc ;==>_Singleton2
et si cela ne fonctionne toujours pas, essayez les différentes fonctions proposées dans ce message :
https://www.autoitscript.com/forum/topi ... nt=1330154
Re: [R] Singleton
Posté : sam. 11 avr. 2020 14:31
par TommyDDR
@Tlem : une explication de pourquoi le singleton normal ne fonctionne pas ?
Re: [R] Singleton
Posté : sam. 11 avr. 2020 16:16
par Tlem
Pas vraiment. Je pense que si jchd passe dans le coin et voit ce message, il devrait sans doute nous apporter quelques explications.
Sinon, d'après ce que j'ai vu, la fonction Singleton2 que j'ai proposé, est presque identique à celle d'origine, elle rajoute simplement quelques contrôles supplémentaires.
Peut-être que dans le lien que j'ai indiqué il y a plus d'explications. ^^
Re: [R] Singleton
Posté : sam. 11 avr. 2020 16:57
par jchd
Je ne constate pas de problème avec ça, compilé (x86 ou x64, #RequireAdmin ou non) et lancé plusieurs fois avant de fermer la première MsgBox :
Code : Tout sélectionner
#include <Misc.au3>
If _Singleton("Célibataire", 1) Then
MsgBox(0, "Singleton", "Seul au monde")
Else
MsgBox(0, "Singleton", "Jumeaux ou plus")
EndIf
W10 x64 v1909, AV = Eset, AU3 v3.3.14.5
Re: [R] Singleton
Posté : sam. 11 avr. 2020 21:38
par Tlem
Moi non plus, mais il semble que dans certain cas (comme celui de faco) cela ne fonctionne pas correctement.
Bien que le sujet soit ancien, d'après ce que j'ai vu sur le forum US d'autres ont eu ce même problème. ^^