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

Poser une question


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_' ;
Jean-Marc a écrit :
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.
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"
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_' ;
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:
As tu les valeurs des constantes
PROC_SYNCHRONIZE
PROCESS_TERMINATE
PROCESS_QUERY_INFORMATION
PROCESS_VM_READ
merci
Driss