[Résolu] Empêcher un exécutable de se lancer plus d'une fois

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Ollivier
Messages : 4190
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: Empêcher un exécutable de se lancer plus d'une fois

Message par Ollivier »

C'est intéressant de voir la notion d'instance. Une instance s'identifie, et là il y a des API Windows qui déterminent les identifications d'instance.

Si on veut être multi-plateforme, il faut déjà considérer la nécessité ou non d'avoir une identification externe d'instance.

Pour exécuter sous condition et créer ou gérer une ou plusieurs instances, ce n'est pas nécessaire de chercher des API. On a besoin de telles APIs quand on doit gérer plusieurs fichiers exécutables et pas forcément issus de PureBasic.

Là, ce n'est pas trop la demande. Alors on peut créer et contrôler soi-même des indentifications d'instance.

On peut par exemple utiliser l'adressage simple

Code : Tout sélectionner

Procedure ProcessGetId()
   ProcedureReturn @ProcessGetId()
EndProcedure
On peut "durcir" l'identification ou, plus précisément son authentification pour le multi-threading :

Code : Tout sélectionner

Procedure ThreadedProcessGetId()
   Define temporary.I
   Mov [p.v_temporary], eax ; ou rax pour du x64
   ProcedureReturn @ThreadedProcessGetId() ! temporary
EndProcedure
En stockant les identificateurs, dans le fichier texte, à la base vide, avec juste Hex(), on peut faire tout autant qu'avec les APIs Windows, mais... En multi-plateforme, donc pour Mac et Linux.

La 2ème fonction ThreadedProcessGetId() permet de gérer des instances sans la contrainte de temps (simultanées/threads).

Enfin, on peut protéger contre un contrôle verreux en cryptant chaque identification d'instance avec la librairie native de cryptage.

Tout ça dans un TXT. On peut enfin se contraindre à ce que chaque process contiennent une copie/image du TXT au cas où une suppression inopinée se produise.
Avatar de l’utilisateur
Micoute
Messages : 2522
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

Re: Empêcher un exécutable de se lancer plus d'une fois

Message par Micoute »

Bon dimanche à tous,

La solution que j'ai trouvée, c'est quand je lance mon programme, il vérifie si un fichier texte portant le même nom que l'exécutable existe et le crée sinon, ensuite il l'efface quand il se termine et c'est très efficace, car avec les autres méthodes si on relance et stoppe le même programme, on finit par devoir relancer l'ordinateur pour pouvoir l'exécuter de nouveau.

Code : Tout sélectionner

…

Procedure Programme_principal()
  If OpenWindow(#Fenetre_Principale, 0, 0, 1045, 800, "Tendances glycémiques", #PB_Window_BorderLess|#PB_Window_ScreenCentered|#PB_Window_Invisible)
    If ReadFile(#Fichier_Txt, Fichier_espion)   ; Si le fichier peut être lu , on indique que l'exécutable est déjà ouvert
      MessageRequester("Attention", "Votre logiciel est déjà ouvert" + #LF$ + #LF$ +
                                    "cette tentative va échouer", #PB_MessageRequester_Info)
      Quitter()
    Else
      CreateFile(#Fichier_Txt, Fichier_espion)
      FileSeek(#Fichier_Txt, Lof(#Fichier_Txt))
      WriteString(#Fichier_Txt, FormatDate("%dd/%mm/%yyyy %hh/%ii/%ss", Date()))
      CloseFile(#Fichier_Txt)
    EndIf  
    Remplir_liste_vierge()
    Programme_saisies()
  EndIf  
EndProcedure

...

Procedure Quitter() ;Fin du programme
  Select EventType()
    Case #PB_EventType_LeftClick
      If FileSize(Fichier_espion) ;Si le fichier existe, on l'efface pour pouvoir le réouvrir après la fermeture
        DeleteFile(Fichier_espion)
      EndIf  
      CloseWindow(EventWindow())
      If Not IsWindow(#Fenetre_Saisies)
        End
      EndIf  
  EndSelect
EndProcedure
Microsoft Windows 10 Famille 64 bits : Carte mère : ASRock 970 Extreme3 R2.0 : Carte Graphique NVIDIA GeForce RTX 3080 : Processeur AMD FX 6300 6 cœurs 12 threads 3,50 GHz PB 5.73 PB 6.00 LTS (x64)
Un homme doit être poli, mais il doit aussi être libre !
Avatar de l’utilisateur
Zorro
Messages : 2185
Inscription : mar. 31/mai/2016 9:06

Re: Empêcher un exécutable de se lancer plus d'une fois

Message par Zorro »

@micoute

et que ce passe t'il si ton prg plante .. sans avoir effacé le fameux fichier ?? :mrgreen:
ou par exemple si on vire ton prg en utilisant Ctrl+Alt+Del
Image
Image
Site: http://michel.dobro.free.fr/
Devise :"dis moi ce dont tu as besoin, je t'expliquerai comment t'en passer"
Avatar de l’utilisateur
Micoute
Messages : 2522
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

Re: Empêcher un exécutable de se lancer plus d'une fois

Message par Micoute »

Tu as parfaitement raison Zorro, dans ce cas précis il ne me reste plus qu'à le faire manuellement, je suppose qu'il existe une meilleure solution pour le faire.
Microsoft Windows 10 Famille 64 bits : Carte mère : ASRock 970 Extreme3 R2.0 : Carte Graphique NVIDIA GeForce RTX 3080 : Processeur AMD FX 6300 6 cœurs 12 threads 3,50 GHz PB 5.73 PB 6.00 LTS (x64)
Un homme doit être poli, mais il doit aussi être libre !
Avatar de l’utilisateur
Ar-S
Messages : 9477
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Empêcher un exécutable de se lancer plus d'une fois

Message par Ar-S »

Tu as lu les messages précédents et essayé les codes ?
On ne peut pas faire plus concis que ça :

Code : Tout sélectionner

;Net Maestro
*a = CreateSemaphore_(null,0,1,"PreviewModeSemaphore")
If *a <> 0 And GetLastError_()= #ERROR_ALREADY_EXISTS
CloseHandle_(*a)
MessageRequester("Erreur","Programme déjà ouvert") ; pas obligatoire
End
EndIf
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Avatar de l’utilisateur
Micoute
Messages : 2522
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

Re: Empêcher un exécutable de se lancer plus d'une fois

Message par Micoute »

Je l'ai déjà dit le pourquoi : "avec les autres méthodes si on relance et stoppe le même programme, on finit par devoir relancer l'ordinateur pour pouvoir l'exécuter de nouveau."
Microsoft Windows 10 Famille 64 bits : Carte mère : ASRock 970 Extreme3 R2.0 : Carte Graphique NVIDIA GeForce RTX 3080 : Processeur AMD FX 6300 6 cœurs 12 threads 3,50 GHz PB 5.73 PB 6.00 LTS (x64)
Un homme doit être poli, mais il doit aussi être libre !
Avatar de l’utilisateur
Ar-S
Messages : 9477
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Empêcher un exécutable de se lancer plus d'une fois

Message par Ar-S »

Micoute a écrit :Je l'ai déjà dit le pourquoi : "avec les autres méthodes si on relance et stoppe le même programme, on finit par devoir relancer l'ordinateur pour pouvoir l'exécuter de nouveau."
Donc ça marche chez tout le monde mais pas chez toi donc les codes ne sont pas bon ?
Faut se remettre un poil en question Micoute. :wink:
ça vient probablement de ton code à toi. (ou te ton windows)
Voilà un test très rapide utilisant le code de NM compilé en pb5.71 x64

Image
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Avatar de l’utilisateur
Micoute
Messages : 2522
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

Re: Empêcher un exécutable de se lancer plus d'une fois

Message par Micoute »

Oui, je sais que ça vient de mon système d'exploitation qui est pourtant la dernière version de W10 64 bits sur mon SSD, j'avais remarqué ce fait quand MLD et moi-même travaillions sur un projet commun qui était destiné à la sensibilisation du diabète où les gadgets et les graphiques étaient tronqués sur mon écran qui a pourtant une résolution de 2560 x 1080 qui fonctionne parfaitement à l'association, et aussi la plupart des programmes en 3D ne fonctionnent pas, car le système ne trouve pas Directx 12, je ne sais plus comment remettre ça en ordre à cause de mon a.v.c. qui m'a fait perdre énormément de connaissances et c'est pourquoi mes enfants m'appellent fishman. Voilà ma vie en quelques lignes.
Microsoft Windows 10 Famille 64 bits : Carte mère : ASRock 970 Extreme3 R2.0 : Carte Graphique NVIDIA GeForce RTX 3080 : Processeur AMD FX 6300 6 cœurs 12 threads 3,50 GHz PB 5.73 PB 6.00 LTS (x64)
Un homme doit être poli, mais il doit aussi être libre !
Marc56
Messages : 2147
Inscription : sam. 08/févr./2014 15:19

Re: Empêcher un exécutable de se lancer plus d'une fois

Message par Marc56 »

Tu as raison Micoute,

Dans certains cas, effectivement, un programme PB utilisant les API directement peut provoquer des comportements aléatoires, c'est pour cela entre-autre que je les évites comme la peste.
(Les autres raisons sont la compatibilité, la difficulté à relire le code et les faux positifs des AV)

Par contre j'ai rarement (voir jamais) eu besoin de redémarrer tout le PC suite à un blocage Windows 10.
Quand bien même la souris ne répond plus (pour cliquer avec le bouton gauche sur la barre de tâches) il reste toujours la possibilité classique: Alt + CTRL + Del et sélectionner "Gestionnaire de Tâches". Est-ce que cela ne marche plus non-plus ?

:wink:
Avatar de l’utilisateur
Micoute
Messages : 2522
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

Re: Empêcher un exécutable de se lancer plus d'une fois

Message par Micoute »

Ce n'est pas que Windows freeze, mais on doit le relancer à cause du même message qui affiche que le programme est déjà lancé, alors qu'on ne le voit pas dans le gestionnaire de tâches.
Microsoft Windows 10 Famille 64 bits : Carte mère : ASRock 970 Extreme3 R2.0 : Carte Graphique NVIDIA GeForce RTX 3080 : Processeur AMD FX 6300 6 cœurs 12 threads 3,50 GHz PB 5.73 PB 6.00 LTS (x64)
Un homme doit être poli, mais il doit aussi être libre !
Avatar de l’utilisateur
Ar-S
Messages : 9477
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Empêcher un exécutable de se lancer plus d'une fois

Message par Ar-S »

Micoute tu peux déjà regarder du coté de Direct X sur ton ordi en ouvrant la commande executer : (Touche WINDOWS + R) puis en tapant dxdiag et en validant.
ça te recherchera les pilotes et t'affichera une fenêtre avec des onglets dont "affichage". Tu pourras y déceler un soucis s'il y en a un.
Je vois pas pourquoi ta config aurait des soucis vue ce que c'est. Tu es bien à jour dans tes pilotes aussi ?
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Marc56
Messages : 2147
Inscription : sam. 08/févr./2014 15:19

Re: Empêcher un exécutable de se lancer plus d'une fois

Message par Marc56 »

À tester, il est vrai que CloseHandle_(*a) ne fonctionne pas (chez moi), le premier fichier n'est pas fermé :?

Code : Tout sélectionner

*a = CreateSemaphore_(null,0,1,"PreviewModeSemaphore")
If *a <> 0 And GetLastError_()= #ERROR_ALREADY_EXISTS
    If MessageRequester("Erreur", 
                        "Le programme est déjà lancé. Faut-il le fermer ?", 
                        #PB_MessageRequester_YesNo) = #PB_MessageRequester_Yes
        MessageRequester("OK", "On ferme le premier programme")
        CloseHandle_(*a)
        End
    EndIf
Else
    MessageRequester("", "Running...")
EndIf
Je reste donc sur mon idée à base de Tasklist.exe (on fait souvent ce type de bidouille en shell sous unix depuis des années 'ps -aux | grep machin') :)
ou sinon, le concept de GallyHC est aussi intéressant (créer et ouvrir un fichier (même vide) dans %temp% et ne pas le refermer, ce qui le rend inaccessible à un autre accès en écriture). Propre, efficace, compatible tous systèmes.

:wink:
Fels
Messages : 12
Inscription : ven. 04/mai/2018 21:04

Re: Empêcher un exécutable de se lancer plus d'une fois

Message par Fels »

Bonjour à tous,

J' ai eu le même problème pour le logiciel que je suis en train de faire et j' ai fini par trouver une solution grâce au forum ( un " singleton procédurale " ) :

Code : Tout sélectionner

;===========================================================
; Pour éviter que le logiciel soit lancé plusieurs fois !!!

Structure ProcInfo ; Ppour les process ci dessous
  Name.s
  PID.l
EndStructure

Procedure ProcessList(List ProcList.ProcInfo())
  Protected pe32.PROCESSENTRY32
  Protected hthSnapshot
  
  pe32\dwSize = SizeOf(PROCESSENTRY32)
  ClearList(ProcList())
  
  hthSnapshot = CreateToolhelp32Snapshot_(#TH32CS_SNAPPROCESS, 0)
  If hthSnapshot
    Process32First_(hthSnapshot, @pe32) 
    While Process32Next_(hthSnapshot, @pe32) 
      If AddElement(ProcList())
        ProcList()\Name = LCase(PeekS(@pe32\szExeFile))
        ProcList()\PID  = pe32\th32ProcessID
      EndIf
    Wend 
    CloseHandle_(hthSnapshot)
  EndIf
  
EndProcedure
 
NewList ProcList.ProcInfo()
 
ProcessList(ProcList())

; TERMINE LE PROGRAMME EN COURS SI UNE  AUTRE OCCURENCE EST LANCéE

nbreProcess = 0
ForEach ProcList()
  
  If ProcList()\Name = "agenda_ver_1_2.exe" ; C'est ICI que tu dois mettre le nom de ton programme !!
    nbreProcess + 1
    If nbreProcess = 2
      End
    EndIf
    
  EndIf  
Next
;===========================================================
Avatar de l’utilisateur
Ar-S
Messages : 9477
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Empêcher un exécutable de se lancer plus d'une fois

Message par Ar-S »

Pas besoin de créer une liste et de tout stocker pour ça.

Code : Tout sélectionner

;===========================================================
; Pour éviter que le logiciel soit lancé plusieurs fois !!!

Declare ProcessList(ProgName$)

Procedure ProcessList(ProgName$)
  Protected pe32.PROCESSENTRY32
  Protected hthSnapshot
  Protected.b result
  
  pe32\dwSize = SizeOf(PROCESSENTRY32)
 
  hthSnapshot = CreateToolhelp32Snapshot_(#TH32CS_SNAPPROCESS, 0)
  If hthSnapshot
    Process32First_(hthSnapshot, @pe32)
    While Process32Next_(hthSnapshot, @pe32)
      If LCase(PeekS(@pe32\szExeFile)) = ProgName$
        result + 1
        If result >1
          Break
        EndIf
      EndIf
    Wend
    CloseHandle_(hthSnapshot)
  EndIf
 ProcedureReturn result
EndProcedure


; ======== A mettre en début de code ==========
instance = ProcessList("test.exe")
If instance > 1
;   MessageRequester("",Str(instance))
  End
EndIf


;=================== TEST ==============================

If OpenWindow(0, 0, 0, 220, 100, "Exemple...", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)

   ButtonGadget  (1, 10, 60, 200, 30, "Je suis un programme")
   
   Repeat
     Event = WaitWindowEvent()
     
     Select Event
     
       Case #PB_Event_Gadget
         Select EventGadget()
           Case 1 
              CloseWindow(0)
              End  
         EndSelect
            
     EndSelect
   Until Event = #PB_Event_CloseWindow
 EndIf

;===========================================================
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Avatar de l’utilisateur
Micoute
Messages : 2522
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

Re: Empêcher un exécutable de se lancer plus d'une fois

Message par Micoute »

Désolé de vous dire ça, mais c'est moi avec ce système, on peut lancer le programme plusieurs fois, ma solution reste la plus sûre, mais pas la meilleure.
Microsoft Windows 10 Famille 64 bits : Carte mère : ASRock 970 Extreme3 R2.0 : Carte Graphique NVIDIA GeForce RTX 3080 : Processeur AMD FX 6300 6 cœurs 12 threads 3,50 GHz PB 5.73 PB 6.00 LTS (x64)
Un homme doit être poli, mais il doit aussi être libre !
Répondre