Shellandwait - executer une application, attendre la fin, et renvoyer son code de retour

Soyez le premier à donner votre avis sur cette source.

Vue 28 784 fois - Téléchargée 2 154 fois

Description

Encore une mini source, qui réponde au Forum.

Ce module, que vous pouvez utiliser dans Excel (et tout ce qui fait du VBA) ou bien VB6 ^^ vous donne accès à la fonction ExecCmd.

Cette fonction va executer la commande que vous passez en parametre, va attendre la fin de ce processus, et renvoyer le code de retour de l'application lancée.

vous pouvez maintenant ouvrir les fichiers avec leurs applications principales (Word, Excel, etc)
et utiliser des variables d'environnement (%COMSPEC% ou %SystemRoot%)

Source / Exemple :


Public Function ExecCmd(ByRef vsCmdLine As String, Optional ByRef vsParameters As String, Optional ByRef vsCurrentDirectory As String = vbNullString, Optional ByVal vnShowCmd As Long = SW_SHOW, Optional ByVal vnTimeOut As Long = 200) As Long
Dim lpShellExInfo As SHELLEXECUTEINFOA
    With lpShellExInfo
        .cbSize = Len(lpShellExInfo)
        .lpDirectory = vsCurrentDirectory
        .lpVerb = "open"
        .lpFile = vsCmdLine
        .lpParameters = vsParameters
        .nShow = vnShowCmd
        .fMask = SEE_MASK_DOENVSUBST Or SEE_MASK_NOCLOSEPROCESS Or SEE_MASK_IDLIST
    End With

    If ShellExecuteEx(lpShellExInfo) Then
        Do While WaitForSingleObject(lpShellExInfo.hProcess, vnTimeOut) = WAIT_TIMEOUT
            DoEvents
        Loop

        GetExitCodeProcess lpShellExInfo.hProcess, ExecCmd
        CloseHandle lpShellExInfo.hProcess
    Else
        ExecCmd = vbError
    End If
End Function

'et les déclarations :

Public Const SEE_MASK_DOENVSUBST As Long = &H200
Public Const SEE_MASK_IDLIST As Long = &H4
Public Const SEE_MASK_NOCLOSEPROCESS As Long = &H40
Public Const SW_HIDE As Long = 0
Public Const SW_SHOW As Long = 5
Public Const WAIT_TIMEOUT As Long = 258&

Public Type SHELLEXECUTEINFOA
    cbSize As Long
    fMask As Long
    hwnd As Long
    lpVerb As String
    lpFile As String
    lpParameters As String
    lpDirectory As String
    nShow As Long
    hInstApp As Long
    lpIDList As Long
    lpClass As String
    hkeyClass As Long
    dwHotKey As Long
    hIcon As Long
    hProcess As Long
End Type

Public Declare Function CloseHandle Lib "kernel32.dll" (ByVal hObject As Long) As Long
Public Declare Function GetExitCodeProcess Lib "kernel32.dll" (ByVal hProcess As Long, ByRef lpExitCode As Long) As Long
Public Declare Function ShellExecuteEx Lib "shell32.dll" (ByRef lpExecInfo As SHELLEXECUTEINFOA) As Long
Public Declare Function WaitForSingleObject Lib "kernel32.dll" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long

Conclusion :


pour le test, un simple :

ExecCmd "Calc.exe"
MsgBox "Calculatrice fermée"

suffit.

la documentation est très claire la dessus :
hProcess will be NULL if no process was launched. For example, if a document to be launched is a URL and an instance of Microsoft Internet Explorer is already running, it will display the document. No new process is launched, and hProcess will be NULL.

en gros, si vous voulez espionner la fermeture d'un document Word, ou d'un URL, pas de soucis, si une instance d'un process a été créé spécialement... si Word est ouvert au prélable, aucune instance n'est crée, on recycle le process existant...

Codes Sources

A voir également

Ajouter un commentaire

Commentaires

PCPT
Messages postés
13298
Date d'inscription
lundi 13 décembre 2004
Statut
Modérateur
Dernière intervention
3 février 2018
24 -
propre et fonctionnel. nikel

ByRef? pourquoi?
et qu'apporte le retour de ExecCmd puisque fermé à la récupération? (donc 0?!)

(pas noté)
PCPT [AFCK]
Renfield
Messages postés
17283
Date d'inscription
mercredi 2 janvier 2002
Statut
Modérateur
Dernière intervention
21 juillet 2019
56 -
Byref parce qu'on transmets un String...
(Byval fais une copie, donc légerement plus lourd)

Byref se met par défault, mais là, c'est clair ! ^^

le code de retour est 0 pour la plupart des application : il indique que tout c'est bien passé. Libre a chacun de renvoyer des codes de retour différents...

cas concret :
ExecCmd lance une application, qui fait un traitement sur une base de données.
selon le code de retour, je sais si l'opération s'est bien déroulée, et peut agir en conséquence.
PCPT
Messages postés
13298
Date d'inscription
lundi 13 décembre 2004
Statut
Modérateur
Dernière intervention
3 février 2018
24 -
donc renvoie <> 0 si problème. ok ;)
(je crois bien que c'est ByVal par défaut)
Renfield
Messages postés
17283
Date d'inscription
mercredi 2 janvier 2002
Statut
Modérateur
Dernière intervention
21 juillet 2019
56 -
Byref, par défaut, c'est certain...

le test est facile :
Private Sub Form_Load()
Dim b As Integer
b = 1
Incrementer b

MsgBox b
End Sub

Private Sub Incrementer(a As Integer)
a = a + 1
End Sub

affiche 2
PCPT
Messages postés
13298
Date d'inscription
lundi 13 décembre 2004
Statut
Modérateur
Dernière intervention
3 février 2018
24 -
j'avais lu le contraire, sans pour autant tester....
rectification très utile! thx
et 10/10 pour le code.
++
PCPT [AFCK]

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.