florantanplan
Messages postés76Date d'inscriptionmardi 11 février 2003StatutMembreDernière intervention 8 septembre 2006
-
7 sept. 2006 à 18:41
geobasic
Messages postés69Date d'inscriptionjeudi 6 novembre 2003StatutMembreDernière intervention 3 octobre 2006
-
8 sept. 2006 à 16:08
Bonjour à tous,
Voilà je fais un p'tit dev en VB6. Celui-ci a pour but de lancer l'exécution d'un exécutable. Je n'ai pas accès aux sources de cet exécutable.
Le problème est que cet exécutable tombe parfois dans l'erreur suivante:
Erreur d'exécution '-2147417848 (80010108)':
Erreur Automation
L'objet invoqué s'est déconnecté de ses clients.
Mon but: détecter le déclenchement de cette erreur, tuer le processus et le relancer.
Jusqu'ici, je procédait de la manière suivante: un timer vient régulièrement vérifier la mémoire utilisée par ce processus. Si celle ci reste à la même valeur trop longtemps, le processus est considéré comme planté et je le tue.
Sauf que ce test sur la mémoire n'et pas fiable. La mémoire utilisée peut être stable pendant un fonctionnement normal... Donc il faut que je trouve autre chose et c'est là que j'ai besoin de vous...
Connaissez vous une API capable de détecter une erreur d'un prcessus externe???
Ou alors je peut peut-être me baser sur l'occupation du CPU mais je ne sais pas remonter cet info...
Ou alors je suis ouvert à toute autre proposition...
Merci d'avance à la bête de VB qui me solutionnera!
PCPT
Messages postés13272Date d'inscriptionlundi 13 décembre 2004StatutMembreDernière intervention 3 février 201847 7 sept. 2006 à 22:21
salut,
tu ne peux pas gérer directement lors de l'arrivée de cette erreur?
cad si erreur Erreur Automation
L'objet invoqué s'est déconnecté de ses clients.
alors etc... ?
florantanplan
Messages postés76Date d'inscriptionmardi 11 février 2003StatutMembreDernière intervention 8 septembre 2006 8 sept. 2006 à 12:54
Hey Mr Brunews le grand admin! Tu n'est pas très constructif! (c'est mal)
Croyez moi, si j'utilise ce prog, c'est parce que j'y suis obligé, et pour répondre à PCPT, je n'ai pas accès aux sources de l'appli qui plante. je le lance juste par un "Shell(<Ligne de commande>)".
Mon éditeur ne veut rien y faire. Donc moi je fait mon petit dev pour palier au problème et pour relancer le soft. Kapich???
Ce qu'il me faudrait, c'est une API capable de remonter l'état d'erreur d'un processus, ou un truc du genre...
geobasic
Messages postés69Date d'inscriptionjeudi 6 novembre 2003StatutMembreDernière intervention 3 octobre 2006 8 sept. 2006 à 14:04
Salut,
Il est possible de faire ce que tu demande avec les api suivantes:
- CreateProcess
- WaitForSingleObject
- GetExitCodeProcess
- CloseHandle
Ces api sont dans Kernel.dll
Le principe: au lieu de lancer la commande par shell on le fait avec CreateProcess et on récupère le handle du process (la procédure CreateProcess est assez compliqué, il y a quelques structures à déclarer et à renseigner avant de l'exécuter). Puis on execute dans une boucle WaitForSingleObject avec un DoEvents jusqu'à que la commande se termine. En sortie de boucle on lance GetExitCodeProcess pour récupérer le code erreur du process, et enfin on ferme le process par CloseHandle.
Si le code erreur correspond, alors on relance tout le processus jusqu'a l'obtention d'un code retour correcte. Cependant si ton exécutable part systématiquement en erreur automation, il faut prévoir une porte de sortie, sinon ton prog va tourner éternèlement.
J'ai déjà utilisé ces api dans le temps, Si je le retrouve dans mes sources je t'envairai un exemple à l'occasion.
geobasic
Messages postés69Date d'inscriptionjeudi 6 novembre 2003StatutMembreDernière intervention 3 octobre 2006 8 sept. 2006 à 16:08
Trouvé ! Voici un exemple de code mettant en pratique les api pré-citées:
Option Explicit
Private Const STARTF_USESTDHANDLES = &H100&
Private Const STARTF_USESHOWWINDOW = &H1
Private Const WAIT_TIMEOUT = &H102
Private Type PROCESS_INFORMATION
hProcess As Long
hThread As Long
dwProcessId As Long
dwThreadId As Long
End Type
Private Type STARTUPINFO
cb As Long
lpReserved As String
lpDesktop As String
lpTitle As String
dwX As Long
dwY As Long
dwXSize As Long
dwYSize As Long
dwXCountChars As Long
dwYCountChars As Long
dwFillAttribute As Long
dwFlags As Long
wShowWindow As Integer
cbReserved2 As Integer
lpReserved2 As Byte
hStdInput As Long
hStdOutput As Long
hStdError As Long
End Type
Private Type SECURITY_ATTRIBUTES
nLength As Long
lpSecurityDescriptor As Long
bInheritHandle As Long
End Type
Private Enum enPriority_Class
NORMAL_PRIORITY_CLASS = &H20
IDLE_PRIORITY_CLASS = &H40
HIGH_PRIORITY_CLASS = &H80
End Enum
'Api de création d'un process
Private Declare Function CreateProcess Lib "kernel32" Alias "CreateProcessA" _
(ByVal lpApplicationName As String, _
ByVal lpCommandLine As String, _
lpProcessAttributes As SECURITY_ATTRIBUTES, _
lpThreadAttributes As SECURITY_ATTRIBUTES, _
ByVal bInheritHandles As Long, _
ByVal dwCreationFlags As Long, _
ByVal lpEnvironment As Long, _
ByVal lpCurrentDirectory As Long, _
lpStartupInfo As STARTUPINFO, _
lpProcessInformation As PROCESS_INFORMATION) As Long
'Verification de l'état d'un process
Private Declare Function WaitForSingleObject Lib "kernel32" _
(ByVal hHandle As Long, _
ByVal dwMilliseconds As Long) As Long
'Fermeture d'un handle
Private Declare Function CloseHandle Lib "kernel32" (ByVal hHandle As Long) As Long
'Api pour vérifier le code Exit du process aprés exécution
Private Declare Function GetExitCodeProcess Lib "kernel32" _
(ByVal hProcess As Long, lpExitCode As Long) As Long
Public Function ExecuteProg(ProgPath) As Long
Dim RetCode As Long
'Structure pour CreateProcess
Dim Startup As STARTUPINFO
Dim Secur As SECURITY_ATTRIBUTES
Dim ProcInfo As PROCESS_INFORMATION
' Code Exit du process
Dim mExitCode As Long
'Renseignement de la structure SECURITY_ATTRIBUTES
Secur.nLength = Len(Secur)
Secur.bInheritHandle = 1&
Secur.lpSecurityDescriptor = 0&
'Renseignement de la structure STARTUPINFO
Startup.cb = Len(Startup)
Startup.dwFlags = STARTF_USESTDHANDLES Or STARTF_USESHOWWINDOW
'Création du process (Exécution du prog)
If CreateProcess(ProgPath, 0&, Secur, Secur, 1&, NORMAL_PRIORITY_CLASS, 0&, 0&, Startup, ProcInfo) <> 1 Then
MsgBox "Executable non trouvé.", vbCritical
Exit Function
End If
'Boucle d'attente de fin du programme
Do
RetCode = WaitForSingleObject(ProcInfo.hProcess, 0&)
DoEvents
Loop While RetCode = WAIT_TIMEOUT
'Obtention du code Exit du process
RetCode = GetExitCodeProcess(ProcInfo.hProcess, mExitCode)
'Fermeture des Handles du process créé
RetCode = CloseHandle(ProcInfo.hProcess)
RetCode = CloseHandle(ProcInfo.hThread)
'Renvoie du code Exit
ExecuteProg = mExitCode
End Function
Ce code est à mettre dans un module. La fonction ExecuteProg execute le programme donnée en paramêtre et renvoie son code Exit aprés exécution.
Voilà ! En espérant que ce petit source puisse t'aider...