[R] Singleton

Aide et conseils concernant AutoIt et ses outils.
Règles du forum
.
Répondre
Faco
Niveau 4
Niveau 4
Messages : 76
Enregistré le : lun. 29 juil. 2013 18:09
Status : Hors ligne

[R] Singleton

#1

Message 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
Modifié en dernier par Faco le sam. 11 avr. 2020 13:19, modifié 1 fois.

Avatar du membre
mikell
Modérateur
Modérateur
Messages : 5994
Enregistré le : dim. 29 mai 2011 17:32
Localisation : Deep Cévennes
Status : Hors ligne

Re: [..] Singleton

#2

Message 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)
" L'échec est le fondement de la réussite. " (Lao-Tseu )
" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )

Avatar du membre
Tlem
Site Admin
Site Admin
Messages : 11556
Enregistré le : ven. 20 juil. 2007 21:00
Localisation : Bordeaux
Status : Hors ligne

Re: [..] Singleton

#3

Message 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. :mrgreen:
Thierry

Rechercher sur le forum ----- Les règles du forum
Le "ça ne marche pas" est une conséquence commune découlant de beaucoup trop de raisons potentielles ...

Une idée ne peut pas appartenir à quelqu'un. (Albert Jacquard) tiré du documentaire "Copié n'est pas volé".

Avatar du membre
TommyDDR
Modérateur
Modérateur
Messages : 1874
Enregistré le : mar. 22 juil. 2008 21:55
Localisation : Nantes
Status : Hors ligne

Re: [..] Singleton

#4

Message 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 :)
3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679

Faco
Niveau 4
Niveau 4
Messages : 76
Enregistré le : lun. 29 juil. 2013 18:09
Status : Hors ligne

Re: [..] Singleton

#5

Message 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.")
   Exit
EndIf

MsgBox(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.

Avatar du membre
Tlem
Site Admin
Site Admin
Messages : 11556
Enregistré le : ven. 20 juil. 2007 21:00
Localisation : Bordeaux
Status : Hors ligne

Re: [..] Singleton

#6

Message 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
Thierry

Rechercher sur le forum ----- Les règles du forum
Le "ça ne marche pas" est une conséquence commune découlant de beaucoup trop de raisons potentielles ...

Une idée ne peut pas appartenir à quelqu'un. (Albert Jacquard) tiré du documentaire "Copié n'est pas volé".

Faco
Niveau 4
Niveau 4
Messages : 76
Enregistré le : lun. 29 juil. 2013 18:09
Status : Hors ligne

Re: [..] Singleton

#7

Message 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 @ScriptName
If _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.")
   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()")
Ça fonctionne chez vous ? Quel version d'autoit pour compiler ?

Avatar du membre
Tlem
Site Admin
Site Admin
Messages : 11556
Enregistré le : ven. 20 juil. 2007 21:00
Localisation : Bordeaux
Status : Hors ligne

Re: [..] Singleton

#8

Message 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.
Thierry

Rechercher sur le forum ----- Les règles du forum
Le "ça ne marche pas" est une conséquence commune découlant de beaucoup trop de raisons potentielles ...

Une idée ne peut pas appartenir à quelqu'un. (Albert Jacquard) tiré du documentaire "Copié n'est pas volé".

Faco
Niveau 4
Niveau 4
Messages : 76
Enregistré le : lun. 29 juil. 2013 18:09
Status : Hors ligne

Re: [..] Singleton

#9

Message par Faco »

2020-04-10 15-51-54.7z
Vidéo de démonstration de mon problème
(1.98 Mio) Téléchargé 23 fois
2020-04-10 15-51-54.7z
Vidéo de démonstration de mon problème
(1.98 Mio) Téléchargé 23 fois
Voila une démo, dites moi où je me trompe svp

Avatar du membre
walkson
Modérateur
Modérateur
Messages : 817
Enregistré le : ven. 12 août 2011 19:49
Localisation : Hurepoix
Status : Hors ligne

Re: [..] Singleton

#10

Message par walkson »

Bonjour,
Recompilez le code et mettre Avast en pose et ça devrait le faire :mrgreen:
Cordialement,
Walkson
"Horas non numero nisi serenas " Le canon de midi
(Je ne compte que les heures heureuses)

Avatar du membre
Tlem
Site Admin
Site Admin
Messages : 11556
Enregistré le : ven. 20 juil. 2007 21:00
Localisation : Bordeaux
Status : Hors ligne

Re: [..] Singleton  

#11

Message 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
Thierry

Rechercher sur le forum ----- Les règles du forum
Le "ça ne marche pas" est une conséquence commune découlant de beaucoup trop de raisons potentielles ...

Une idée ne peut pas appartenir à quelqu'un. (Albert Jacquard) tiré du documentaire "Copié n'est pas volé".

Avatar du membre
walkson
Modérateur
Modérateur
Messages : 817
Enregistré le : ven. 12 août 2011 19:49
Localisation : Hurepoix
Status : Hors ligne

Re: [..] Singleton

#12

Message 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 :mrgreen: ) que je suis....
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Outfile=singleton_1.exe
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

If Not @Compiled Then Exit MsgBox(16,"","doit être compilé")
Local $array = ProcessList(@ScriptName)
If $array[0][0] > 1 Then Exit MsgBox(16,"","déjà une instance")

MsgBox(32,@ScriptName,"ça tourne")
Cordialement,
Walkson
"Horas non numero nisi serenas " Le canon de midi
(Je ne compte que les heures heureuses)

Faco
Niveau 4
Niveau 4
Messages : 76
Enregistré le : lun. 29 juil. 2013 18:09
Status : Hors ligne

Re: [R] Singleton

#13

Message 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

Avatar du membre
TommyDDR
Modérateur
Modérateur
Messages : 1874
Enregistré le : mar. 22 juil. 2008 21:55
Localisation : Nantes
Status : Hors ligne

Re: [R] Singleton

#14

Message par TommyDDR »

@Tlem : une explication de pourquoi le singleton normal ne fonctionne pas ?
3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679

Avatar du membre
Tlem
Site Admin
Site Admin
Messages : 11556
Enregistré le : ven. 20 juil. 2007 21:00
Localisation : Bordeaux
Status : Hors ligne

Re: [R] Singleton

#15

Message 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. ^^
Thierry

Rechercher sur le forum ----- Les règles du forum
Le "ça ne marche pas" est une conséquence commune découlant de beaucoup trop de raisons potentielles ...

Une idée ne peut pas appartenir à quelqu'un. (Albert Jacquard) tiré du documentaire "Copié n'est pas volé".

Avatar du membre
jchd
AutoIt MVPs (MVP)
AutoIt MVPs (MVP)
Messages : 2138
Enregistré le : lun. 30 mars 2009 22:57
Localisation : Sud-Ouest de la France (43.622788,-1.260864)
Status : Hors ligne

Re: [R] Singleton

#16

Message 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
La cryptographie d'aujourd'hui c'est le taquin plus l'électricité.

Avatar du membre
Tlem
Site Admin
Site Admin
Messages : 11556
Enregistré le : ven. 20 juil. 2007 21:00
Localisation : Bordeaux
Status : Hors ligne

Re: [R] Singleton

#17

Message 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. ^^
Thierry

Rechercher sur le forum ----- Les règles du forum
Le "ça ne marche pas" est une conséquence commune découlant de beaucoup trop de raisons potentielles ...

Une idée ne peut pas appartenir à quelqu'un. (Albert Jacquard) tiré du documentaire "Copié n'est pas volé".

Répondre