Utilisation de ExecCmd

Résolu
cs_PROGRAMMIX Messages postés 1133 Date d'inscription mercredi 2 octobre 2002 Statut Membre Dernière intervention 24 juillet 2011 - 16 déc. 2007 à 18:34
cs_PROGRAMMIX Messages postés 1133 Date d'inscription mercredi 2 octobre 2002 Statut Membre Dernière intervention 24 juillet 2011 - 18 déc. 2007 à 20:03
Bonjour

Dans une application, j'affiche une feuille fille dans laquelle se trouve un bouton permettant de lancer une autre application en utilisant le code suivant :

    Dim retval As Long
   
    If AfficherFormulaire Then
        retval = ExecCmd(App.Path & "\ListeDuPersonnel.exe " & RepertoirePersonnel & "FichierDuPersonnel.txt")
    End If
   
    ListeSalariés.LireLeCarnet (RepertoirePersonnel & "FichierDuPersonnel.txt")

Mais si, je ferme ma feuille fille sans avoir précédamment fermer l'application appelée, ça plante.
Théoriquement, je ne devrais pas procéder ainsi, mais ceci est une projection d'une mauvaise manipulation de la part d'un utilisateur lambda.

Que devrais-je faire pour éviter cela ?

Programmix

6 réponses

cs_PROGRAMMIX Messages postés 1133 Date d'inscription mercredi 2 octobre 2002 Statut Membre Dernière intervention 24 juillet 2011 2
18 déc. 2007 à 20:03
Merci Renfield pour ton code.

Je n'ai pas testé les possibilités que tu proposes avec le proc.hProcess et le QueryUnload.

Je verrai peut-être cela plus tard, mais pour l'instant, ton code me convient.

Programmix
3
jmfmarques Messages postés 7666 Date d'inscription samedi 5 novembre 2005 Statut Membre Dernière intervention 22 août 2014 27
16 déc. 2007 à 19:49
Bonjour,

Euh...

Et si tu nous parlais de la fonction ExecCmd qui n'est ni une fonction de VB ni une fonction de l'Api de Windows (du moins à ma connaissance) ?

Tu as apparemment donné ce nom à une fonction ... (tu aurais pu l'appeler toto...)

Que fait-elle (son code ) ?
0
cs_PROGRAMMIX Messages postés 1133 Date d'inscription mercredi 2 octobre 2002 Statut Membre Dernière intervention 24 juillet 2011 2
16 déc. 2007 à 20:35
OUPS,

Effectivement, c'est une fonction qui appelle la procédure suivante qui appelle certaines API :

Public Function ExecCmd(cmdline$)
     
    Dim proc As PROCESS_INFORMATION
    Dim start As STARTUPINFO
    Dim ret&
   
    ' Initialisez la structure STARTUPINFO :
    start.cb = Len(start)

    ' Démarrez l'application Shell :
    ret& = CreateProcessA(vbNullString, cmdline$, 0&, 0&, 1&, NORMAL_PRIORITY_CLASS, 0&, vbNullString, start, proc)

    ' Attendez la fin de l'application Shell :
    ret& = WaitForSingleObject(proc.hProcess, INFINITE)
    Call GetExitCodeProcess(proc.hProcess, ret&)
    Call CloseHandle(proc.hThread)
    Call CloseHandle(proc.hProcess)
    ExecCmd = ret&

End Function

Les variables et déclarations sont les suivantes :

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 Long
    hStdInput As Long
    hStdOutput As Long
    hStdError As Long
End Type

Private Type PROCESS_INFORMATION
    hProcess As Long
    hThread As Long
    dwProcessID As Long
    dwThreadID As Long
End Type

Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long

Private Declare Function CreateProcessA Lib "kernel32" (ByVal lpApplicationName As String, ByVal lpCommandLine As String, _
        ByVal lpProcessAttributes As Long, ByVal lpThreadAttributes As Long, _
        ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, _
        ByVal lpEnvironment As Long, ByVal lpCurrentDirectory As String, _
        lpStartupInfo As STARTUPINFO, lpProcessInformation As PROCESS_INFORMATION) As Long

Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long

Private Declare Function GetExitCodeProcess Lib "kernel32" (ByVal hProcess As Long, lpExitCode As Long) As Long

Private Const NORMAL_PRIORITY_CLASS = &H20&
Private Const INFINITE = -1&

Programmix
0
jmfmarques Messages postés 7666 Date d'inscription samedi 5 novembre 2005 Statut Membre Dernière intervention 22 août 2014 27
16 déc. 2007 à 21:20
Juste une question :

Si ce n'est que pour faire celà, pourquoi n'utilises-tu pas directement la fonction ShellExecute de l'Api de Windows, voire la fonction Shell de VB ?

genre :

Private RetVal As Long



Private Sub Command1_Click()
    RetVal = Shell("C:\WINNT\notepad.EXE", 1)    ' Run Calculator.
End Sub


 Et tu ne serais pas "planté" en fermant ta form Fille ...
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_PROGRAMMIX Messages postés 1133 Date d'inscription mercredi 2 octobre 2002 Statut Membre Dernière intervention 24 juillet 2011 2
16 déc. 2007 à 21:30
C'est qu'avec ShellExecute, la procédure n'attend pas la fermeture de l'exe avant de continuer.

Or dans mon cas, il me faut attendre avant de pouvoir recharger le fichier avec les données modifiées via l'exe en question.

Programmix
0
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
17 déc. 2007 à 07:17
vu que tu as le proc.hProcess, tu es en mesure de forcer la fermeture de l'application distante (via API) lorsque l'utilisateur souhaite fermer la form fille.

autre possibilité, empecher la fermeture de la fenetre fille tant que l'appi en question n'est pas fermée (dans QueryUnload)

tiens une version plus complète de ExecCmd:

http://www.vbfrance.com/codes/SHELLANDWAIT-EXECUTER-APPLICATION-ATTENDRE-FIN-RENVOYER-SON-CODE_34867.aspx
0
Rejoignez-nous