GNT sans publicité, site mobile, fonctionnalitées exclusives...

App.PrevInstance

Le
Damien DEFEUX
Bonjour,

J'utilise App.PrevInstance depuis des années pour n'avoir mon application
ouverte qu'une seule fois. Mais j'ai eu plusieurs fois le cas où
App.PrevInstance m'indique que l'application est déjà lancée alors que ce
n'est pas le cas (pas de processus dans le gestionnaire de taches).

J'ai deux questions par rapport à ça :

- Quelqu'un sait-il comment fonctionne le App.PrevInstance et sur quoi il
se base ?

- Quelles sont les alternatives pour remplacer App.PrevInstance ?

Merci d'avance.

Dams
Lire les 7 réponses

Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses Page 1 / 2
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Jean-Marc
Le #21547121
On Apr 13, 2:49 pm, "Damien DEFEUX"
Bonjour,

J'utilise App.PrevInstance depuis des années pour n'avoir mon applicati on
ouverte qu'une seule fois. Mais j'ai eu plusieurs fois le cas où
App.PrevInstance m'indique que l'application est déjà lancée alors que ce
n'est pas le cas (pas de processus dans le gestionnaire de taches).



Hello,
si tu as ce genre de comportements, c'est que ton application est
toujours chargée en mémoire. Tu ne la vois pas dans la partie
"Applications" du gestionnaire de taches, mais elle peut etre encore à
l'état de zombie dans la partie "Processus". Il y a plein de causes à
ce genre de problèmes, le plus classique étant un programme VB ayant
instancié un objet ActiveX (Word, Excel, etc) et ayant quitté
anormalement ou sans faire le cleanup nécessaire.
Il y a des API qui font ce que fait App.PrevInstance, mais ce sera la
même chose car APP.Previnstance utilise ces API.

Cordialement,


--
Jean-marc Noury (jean_marc_n2)
FAQ VB: http://faq.vb.free.fr/
mailto: remove '_no_spam_' ;
Jacques93
Le #21547491
Bonjour Jean-Marc,
Jean-Marc a écrit :
On Apr 13, 2:49 pm, "Damien DEFEUX"
Bonjour,

J'utilise App.PrevInstance depuis des années pour n'avoir mon application
ouverte qu'une seule fois. Mais j'ai eu plusieurs fois le cas où
App.PrevInstance m'indique que l'application est déjà lancée alors que ce
n'est pas le cas (pas de processus dans le gestionnaire de taches).



Hello,
si tu as ce genre de comportements, c'est que ton application est
toujours chargée en mémoire. Tu ne la vois pas dans la partie
"Applications" du gestionnaire de taches, mais elle peut etre encore à
l'état de zombie dans la partie "Processus". Il y a plein de causes à
ce genre de problèmes, le plus classique étant un programme VB ayant
instancié un objet ActiveX (Word, Excel, etc) et ayant quitté
anormalement ou sans faire le cleanup nécessaire.
Il y a des API qui font ce que fait App.PrevInstance, mais ce sera la
même chose car APP.Previnstance utilise ces API.




Tout à fait d'accord, mais dans le cas de process zombie, on peux killer
le zombie. Dans le fil de driss hanib concernant App.Previnstance, je
n'avais pas indiqué le code, le voici (sans les déclarations) :

Public Sub Main()
If App.PrevInstance Then
Dim ThreadId As Long, PID As Long
Dim hProcess As Long, lResult As Long

hWnd = FindWindow("ThunderRT6MDIForm", "Caption de la fenêtre")
On Error Resume Next
Err.Clear
AppActivate "Caption de la fenêtre"
If Err.Number ' Err = 5 si Process actif et fenetre invisible
' (en général suite à plantage)
If hWnd <> 0 Then
' Recupere le ProcessId via le handle de la fenetre invisible
ThreadId = GetWindowThreadProcessId(hWnd, PID)
Else
' ou en balayant la table des process si le process ne répond pas
PID = GetProcessPID("NomExe.exe")
End If
' Ouverture et suppresion du process
hProcess = OpenProcess(PROC_SYNCHRONIZE Or PROCESS_TERMINATE, 0, PID)
If hProcess Then
lResult = TerminateProcess(hProcess, 0)
CloseHandle hProcess
End If
Else
' Sinon restaure / reactive la fenetre
If IsIconic(hWnd) Then
X = ShowWindow(hWnd, SW_RESTORE)
Else
X = ShowWindow(hWnd, SW_SHOW)
End If
End
End If
End If
End Sub


Public Function GetProcessPID(ModName As String) As Long
Const MAX_PROCESS As Long = 4096
Dim lResult As Long
Dim cb As Long, cbNeeded As Long
Dim Process(MAX_PROCESS) As Long
Dim nbProcess As Long, i As Long
Dim PID As Long

cb = Len(Process(0)) * MAX_PROCESS
lResult = EnumProcesses(Process(0), cb, cbNeeded)
nbProcess = cbNeeded / Len(Process(0))
For i = 0 To nbProcess - 1
PID = GetProcessInfo(ModName, Process(i))
If PID <> 0 Then
GetProcessPID = PID
Exit Function
End If
Next i
End Function

Private Function GetProcessInfo(ModName As String, PID As Long) As Long
Dim hProcess As Long
Dim lResult As Long
Dim cb As Long, cbNeeded As Long
Dim Modules(0 To 199) As Long
Dim ModuleName As String
Dim nbModule As Long
Dim pmc As PROCESS_MEMORY_COUNTERS

GetProcessInfo = 0
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION Or PROCESS_VM_READ,
0, PID)
If hProcess Then
cb = 200
lResult = EnumProcessModules(hProcess, Modules(0), 200, cbNeeded)
If lResult <> 0 Then
ModuleName = Space(MAX_PATH)
cb = 500
lResult = GetModuleFileNameExA(hProcess, Modules(0), ModuleName, cb)
ModuleName = Left(ModuleName, lResult)
ModuleName = Mid(ModuleName, InStrRev(ModuleName, "") + 1)
pmc.cb = Len(pmc)
lResult = GetProcessMemoryInfo(hProcess, pmc, pmc.cb)
If UCase(ModName) = UCase(ModuleName) Then
GetProcessInfo = PID
End If
End If
CloseHandle hProcess
End If
End Function


--

Cordialement,

Jacques.
Damien DEFEUX
Le #21547881
J'ai regardé dans les processus, il n'y a rien.

J'ai fait un taskkill de mon application et malgres ça j'ai toujours
App.PrevInstance qui est vrai.

J'ai regardé avec un utilitaire qui affiche les process et je vois pas mon
appli.



"Jean-Marc"
On Apr 13, 2:49 pm, "Damien DEFEUX"
Bonjour,

J'utilise App.PrevInstance depuis des années pour n'avoir mon application
ouverte qu'une seule fois. Mais j'ai eu plusieurs fois le cas où
App.PrevInstance m'indique que l'application est déjà lancée alors que ce
n'est pas le cas (pas de processus dans le gestionnaire de taches).



Hello,
si tu as ce genre de comportements, c'est que ton application est
toujours chargée en mémoire. Tu ne la vois pas dans la partie
"Applications" du gestionnaire de taches, mais elle peut etre encore à
l'état de zombie dans la partie "Processus". Il y a plein de causes à
ce genre de problèmes, le plus classique étant un programme VB ayant
instancié un objet ActiveX (Word, Excel, etc) et ayant quitté
anormalement ou sans faire le cleanup nécessaire.
Il y a des API qui font ce que fait App.PrevInstance, mais ce sera la
même chose car APP.Previnstance utilise ces API.

Cordialement,


--
Jean-marc Noury (jean_marc_n2)
FAQ VB: http://faq.vb.free.fr/
mailto: remove '_no_spam_' ;
Driss HANIB
Le #21553421
Bonjour Jacques

tu fais ton petit cachotier ? ;o))
Ton exemple complet est plus "robuste"; je le prends "as it"

merci

Driss

"Jacques93" a écrit dans le message de news:

Bonjour Jean-Marc,
Jean-Marc a écrit :
On Apr 13, 2:49 pm, "Damien DEFEUX"
Bonjour,

J'utilise App.PrevInstance depuis des années pour n'avoir mon
application
ouverte qu'une seule fois. Mais j'ai eu plusieurs fois le cas où
App.PrevInstance m'indique que l'application est déjà lancée alors que
ce
n'est pas le cas (pas de processus dans le gestionnaire de taches).



Hello,
si tu as ce genre de comportements, c'est que ton application est
toujours chargée en mémoire. Tu ne la vois pas dans la partie
"Applications" du gestionnaire de taches, mais elle peut etre encore à
l'état de zombie dans la partie "Processus". Il y a plein de causes à
ce genre de problèmes, le plus classique étant un programme VB ayant
instancié un objet ActiveX (Word, Excel, etc) et ayant quitté
anormalement ou sans faire le cleanup nécessaire.
Il y a des API qui font ce que fait App.PrevInstance, mais ce sera la
même chose car APP.Previnstance utilise ces API.




Tout à fait d'accord, mais dans le cas de process zombie, on peux killer
le zombie. Dans le fil de driss hanib concernant App.Previnstance, je
n'avais pas indiqué le code, le voici (sans les déclarations) :

Public Sub Main()
If App.PrevInstance Then
Dim ThreadId As Long, PID As Long
Dim hProcess As Long, lResult As Long

hWnd = FindWindow("ThunderRT6MDIForm", "Caption de la fenêtre")
On Error Resume Next
Err.Clear
AppActivate "Caption de la fenêtre"
If Err.Number ' Err = 5 si Process actif et fenetre invisible
' (en général suite à plantage)
If hWnd <> 0 Then
' Recupere le ProcessId via le handle de la fenetre invisible
ThreadId = GetWindowThreadProcessId(hWnd, PID)
Else
' ou en balayant la table des process si le process ne répond pas
PID = GetProcessPID("NomExe.exe")
End If
' Ouverture et suppresion du process
hProcess = OpenProcess(PROC_SYNCHRONIZE Or PROCESS_TERMINATE, 0,
PID)
If hProcess Then
lResult = TerminateProcess(hProcess, 0)
CloseHandle hProcess
End If
Else
' Sinon restaure / reactive la fenetre
If IsIconic(hWnd) Then
X = ShowWindow(hWnd, SW_RESTORE)
Else
X = ShowWindow(hWnd, SW_SHOW)
End If
End
End If
End If
End Sub


Public Function GetProcessPID(ModName As String) As Long
Const MAX_PROCESS As Long = 4096
Dim lResult As Long
Dim cb As Long, cbNeeded As Long
Dim Process(MAX_PROCESS) As Long
Dim nbProcess As Long, i As Long
Dim PID As Long

cb = Len(Process(0)) * MAX_PROCESS
lResult = EnumProcesses(Process(0), cb, cbNeeded)
nbProcess = cbNeeded / Len(Process(0))
For i = 0 To nbProcess - 1
PID = GetProcessInfo(ModName, Process(i))
If PID <> 0 Then
GetProcessPID = PID
Exit Function
End If
Next i
End Function

Private Function GetProcessInfo(ModName As String, PID As Long) As Long
Dim hProcess As Long
Dim lResult As Long
Dim cb As Long, cbNeeded As Long
Dim Modules(0 To 199) As Long
Dim ModuleName As String
Dim nbModule As Long
Dim pmc As PROCESS_MEMORY_COUNTERS

GetProcessInfo = 0
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION Or PROCESS_VM_READ, 0,
PID)
If hProcess Then
cb = 200
lResult = EnumProcessModules(hProcess, Modules(0), 200, cbNeeded)
If lResult <> 0 Then
ModuleName = Space(MAX_PATH)
cb = 500
lResult = GetModuleFileNameExA(hProcess, Modules(0), ModuleName, cb)
ModuleName = Left(ModuleName, lResult)
ModuleName = Mid(ModuleName, InStrRev(ModuleName, "") + 1)
pmc.cb = Len(pmc)
lResult = GetProcessMemoryInfo(hProcess, pmc, pmc.cb)
If UCase(ModName) = UCase(ModuleName) Then
GetProcessInfo = PID
End If
End If
CloseHandle hProcess
End If
End Function


--

Cordialement,

Jacques.
Driss HANIB
Le #21553411
salut jacques

As tu les valeurs des constantes
PROC_SYNCHRONIZE
PROCESS_TERMINATE
PROCESS_QUERY_INFORMATION
PROCESS_VM_READ

merci

Driss
Publicité
Suivre les réponses
Poster une réponse
Anonyme