Shell [Résolu]

Signaler
Messages postés
4822
Date d'inscription
lundi 11 novembre 2002
Statut
Membre
Dernière intervention
15 novembre 2016
-
 Sinsitrus -
Bonjour à tous,
Ext-il possible tu tuer un processus lancer par Shell?
Exemple je lance la calculatrice de windows : shell(C:\windows\system32\Calc.exe"), et je voudrais comprendre quand je quitte mon prog que la calculatrice se ferme en même temps!!!lol.
Moi je ne sais pas.
Merci à tous de votre aide.
BON REVEILLON
A+
Exploreur

25 réponses

Messages postés
7741
Date d'inscription
mercredi 1 septembre 2004
Statut
Membre
Dernière intervention
24 septembre 2014
37
Et non lilo, ce n'est pas la bonne explication.

Les applis lancées par Shell, sont des applis indépendantes, et non pas enfants.

Explorer, un petite recherche sur Codix te donne entre autre cet exemple :

http://www.codyx.org/snippet_fermer-application-identifiee-son-titre_17.aspx

sinon, tu as aussi cette petite fonction utilisant les objets WMI trouvée dans le commentaire d'une source de ce site

Function killprocess(ProcessName)
dim objWMIService,colProcesses,objProcess
strComputer = "."

Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\" & strComputer & "\root\cimv2")
Set colProcesses = objWMIService.ExecQuery ("Select * from Win32_Process")        ' where Name='IEXPLORE.EXE'

For Each objProcess in colProcesses
if instr(objProcess.Name,ProcessName)<>0 Then
objProcess.Terminate()
End If
Next
End Function

En espérant répondre à ta question

---- Sevyc64  (alias Casy) ----<hr size="2" width="100%" /># LE PARTAGE EST NOTRE FORCE #
Messages postés
1854
Date d'inscription
jeudi 23 mai 2002
Statut
Membre
Dernière intervention
24 juin 2018
26
 Bonjour à tous

Casy, bonjour,
le if peut-être enlevé.
La méthode est radicale, elle kille tous les processes 'calc'.
Je regarde côté shell, car il y a possibilité d'arrêt "proprement" le prog, ici, la calc, puisque lancé par shell.

'Arrêt d'un Process
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate}!\" _
    & strComputer & "\root\cimv2")
Set colProcessList = objWMIService.ExecQuery _
    ("Select * from Win32_Process Where Name = 'calc.exe'")
For Each objProcess in colProcessList
    'MsgBox objProcess.Name &vbCrLf& " id:" & objProcess.ProcessID
    objProcess.Terminate()
Next



Set objWMIService = Nothing
Set colProcessList = Nothing




jean-marc
Messages postés
1812
Date d'inscription
mardi 31 mai 2005
Statut
Membre
Dernière intervention
26 octobre 2010
1
Violent Ken

Salut à tous.

Je pense personnellement que le sendkeys est une TRES mauvaise idée, tout comme le WMI.

Le plus simple pour tuer un processus est de récupérer son PID. Voici un exemple (coller dans une form) :

Option Explicit


Private Declare Function TerminateProcess Lib "kernel32" (ByVal ApphProcess As Long, ByVal uExitCode As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Declare Function OpenProcess Lib "kernel32.dll" (ByVal dwDesiredAccessas As Long, ByVal bInheritHandle As Long, ByVal dwProcId As Long) As Long


Private Const PROCESS_TERMINAT              As Long = &H1
Private PID As Long


'-------------------------------------------------------
'termine un processus en fonction de son PID
'-------------------------------------------------------
Public Function TerminateProc(ByVal PID As Long) As Long
Dim lhwndProcess As Long
Dim lRep As Long
Dim lExitCode As Long
   
    'ouvre le process en question
    lhwndProcess = OpenProcess(PROCESS_TERMINAT, 0, PID)
   
    'kill le processus
    TerminateProc = TerminateProcess(lhwndProcess, lExitCode)
   
    'ferme le handle
    CloseHandle lhwndProcess


End Function


Private Sub Form_Load()
    PID = Shell("calc.exe") 'lance le process
End Sub


Private Sub Form_Unload(Cancel As Integer)
    TerminateProc PID   'kill le process
End Sub

@+
Messages postés
1812
Date d'inscription
mardi 31 mai 2005
Statut
Membre
Dernière intervention
26 octobre 2010
1
Violent Ken

Salut, hum, pour détecter si la calculatrice est ouverte, je propose ceci :
on vérifie que le path du processus désigné par le PID est bien le path de la calculatrice. Si c'est le cas, alors elle est lancée, sinon on la relance.

Dans le code qui suit, GetPathFromPID obtient le path d'un processus à partir de son PID.

A coller dans une FORM : (command1 relançant la calculatrice si nécessaire) :

Option Explicit


Private Declare Function TerminateProcess Lib "kernel32" (ByVal ApphProcess As Long, ByVal uExitCode As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Declare Function OpenProcess Lib "kernel32.dll" (ByVal dwDesiredAccessas As Long, ByVal bInheritHandle As Long, ByVal dwProcId As Long) As Long


Private Const PROCESS_TERMINAT              As Long = &H1
Private PID As Long


'-------------------------------------------------------
'termine un processus en fonction de son PID
'-------------------------------------------------------
Public Function TerminateProc(ByVal PID As Long) As Long
Dim lhwndProcess As Long
Dim lRep As Long
Dim lExitCode As Long
   
    'ouvre le process en question
    lhwndProcess = OpenProcess(PROCESS_TERMINAT, 0, PID)
   
    'kill le processus
    TerminateProc = TerminateProcess(lhwndProcess, lExitCode)
   
    'ferme le handle
    CloseHandle lhwndProcess


End Function


Private Sub Command1_Click()
'relance la calculette si pas présente
    If LCase$(Right$(GetPathFromPID(PID), 9)) <> "\calc.exe" Then PID = Shell("calc.exe")
End Sub


Private Sub Form_Load()
    PID = Shell("calc.exe") 'lance le process
End Sub


Private Sub Form_Unload(Cancel As Integer)
    TerminateProc PID   'kill le process
End Sub

A coller dans un MODULE :

Option Explicit


'-------------------------------------------------------
'CONSTANTES
'-------------------------------------------------------
Private Const PROCESS_QUERY_INFORMATION     As Long = 1024
Private Const PROCESS_VM_READ               As Long = 16


'-------------------------------------------------------
'APIs
'-------------------------------------------------------
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Declare Function OpenProcess Lib "kernel32.dll" (ByVal dwDesiredAccessas As Long, ByVal bInheritHandle As Long, ByVal dwProcId As Long) As Long
Private Declare Function GetModuleFileNameExA Lib "PSAPI.DLL" (ByVal hProcess As Long, ByVal hModule As Long, ByVal ModuleName As String, ByVal nSize As Long) As Long
Private Declare Function EnumProcessModules Lib "PSAPI.DLL" (ByVal hProcess As Long, ByRef lphModule As Long, ByVal cb As Long, ByRef cbNeeded As Long) As Long


'-------------------------------------------------------
'fonction renvoyant le nom complet du fichier en fonction du PID du processus
'-------------------------------------------------------
Public Function GetPathFromPID(ByVal PID As Long) As String
Dim lHprcss As Long
Dim Ret As Long
Dim sResult As String
Dim hModule As Long


    On Error GoTo ErrGest


    If PID = 0 Then
        GetPathFromPID = "[System Process]"
    ElseIf PID = 4 Then
        GetPathFromPID = "System"
    Else
        'création d'un buffer
        sResult = Space$(512)
       
        lHprcss = OpenProcess(PROCESS_QUERY_INFORMATION Or PROCESS_VM_READ, 0, PID)    'recupère un handle du processus
       
        If lHprcss = 0 Then
        'erreur d'accès
        'MsgBox GetLastError = 5
            Exit Function   'echec
        End If
       
        'handle du module du fichier *.exe
        EnumProcessModules lHprcss, hModule, 4&, Ret
        'buffer
        sResult = Space(260) 'max path
        'obtient le path
        GetModuleFileNameExA lHprcss, hModule, sResult, 260
        'ferme le handle
        CloseHandle lHprcss
        'formate la string
        GetPathFromPID = FormatedString(sResult)  'Left$(sResult, InStr(sResult, vbNullChar) - 1)
    End If
   
ErrGest:
    CloseHandle lHprcss
End Function


'-------------------------------------------------------
'formatage de string
'-------------------------------------------------------
Private Function FormatedString(ByVal sString As String) As String
Dim s As String


    s = sString
   
    'enlève le vbnullchar de fin si nécessaire
    If InStr(s, vbNullChar) Then s = Left$(s, InStr(s, vbNullChar) - 1)
   
    'enlève les espaces inutiles
    s = Trim$(s)
   
    FormatedString = s
End Function

@+
Messages postés
174
Date d'inscription
vendredi 25 janvier 2002
Statut
Membre
Dernière intervention
15 février 2007
2
parce que je suppose que la calculatrice est un processus enfant .
comme vous fermez le logiciel parent (votre prog), tous les enfants sont tués ......

Mortel comme explication .....

--------> [] je sors et rassurez vous, j emmene avec moi cette blague pourrie
Messages postés
4822
Date d'inscription
lundi 11 novembre 2002
Statut
Membre
Dernière intervention
15 novembre 2016
13
oueh...pour les blagues ya mieux....Par contre une réponse sans blague serait la bienvenue!!!
A+
Exploreur
Messages postés
174
Date d'inscription
vendredi 25 janvier 2002
Statut
Membre
Dernière intervention
15 février 2007
2
non mais je pense que c'est la bonne explication par contre ^^
Messages postés
174
Date d'inscription
vendredi 25 janvier 2002
Statut
Membre
Dernière intervention
15 février 2007
2
hum . je viens de tester et visiblement, j ai pas compris la phrase initial.

Quand on ferme le logiciel VB, le logiciel executé en shell reste ouvert et donc je suppose que la question est "comment fermer le logiciel en meme temps" .

Faut dire que la phrase de votre premier post est pas vraiment ecrite avec notre belle langue francaise ^^

Du coup, pour fermer le log, il faut récuprer l ID je crois
Messages postés
4822
Date d'inscription
lundi 11 novembre 2002
Statut
Membre
Dernière intervention
15 novembre 2016
13
Lilo44 >> Quel intérêt de lancer la calculatrice Windows de VB, si ce n'est que de l'incorporer dans une source, le sens de ma question est là!!!Quitte source >> Kill processus de shell!Et puis l'ID ne concerne que cela et non la fermeture :



,

,

,

----

vbHide,
0,
La fenêtre est masquée et activée.,

----

vbNormalFocus,
1,
La fenêtre est activée et rétablie à sa taille et à sa position d'origine.,

----

vbMinimizedFocus,
2,
La fenêtre est affichée sous forme d'icône et activée.,

----

vbMaximizedFocus,
3,
La fenêtre est agrandie et activée.,

----

vbNormalNoFocus,
4,
La fenêtre est rétablie à sa taille et à sa position les plus récentes. La fenêtre active reste active.,

----

vbMinimizedNoFocus,
6,
La fenêtre est affichée sous forme d'icône. La fenêtre active reste active.




Casy >> Merci des informations, je vais essayer tous cela est te tiendrais au courant, car là je dois sortir avec mes gosses qui font les fous!!!!Vont se défouler dehors..A+

Exploreur
Messages postés
174
Date d'inscription
vendredi 25 janvier 2002
Statut
Membre
Dernière intervention
15 février 2007
2
avec ce ptit script, tous les processus calculatrices seront fermé si il y en a plusieurs non ?

simple question histoire de  bien comprendre :)
Messages postés
1854
Date d'inscription
jeudi 23 mai 2002
Statut
Membre
Dernière intervention
24 juin 2018
26
 Re,

Lancement et arrêt avec shell.
Pour une fois, Sendkeys est utile.

Dim WshShell, oCalc
Set WshShell = CreateObject("WScript.Shell")
Set oCalc = WshShell.Exec("calc")
WScript.Sleep 1500



WshShell.AppActivate oCalc.ProcessID
WshShell.SendKeys "%{F4}"



Set WshShell = Nothing
Set oCalc = Nothing






Sinon avec wmi, il faut mettre dans la quéry ProcessId='oCalc.ProcessId' à la place de Name=...

jean-marc
Messages postés
174
Date d'inscription
vendredi 25 janvier 2002
Statut
Membre
Dernière intervention
15 février 2007
2
pfff, je dors a moitié la .. la réponse a ma question est dans le premier post de JMO :s
Messages postés
1854
Date d'inscription
jeudi 23 mai 2002
Statut
Membre
Dernière intervention
24 juin 2018
26
Re,

Je suis en plein apprentissage.
Le shell suffit, sans Sendkeys, ni wmi.

Dim WshShell, oCalc, oNotepad
Set WshShell = CreateObject("WScript.Shell")
Set oCalc = WshShell.Exec("calc")



WScript.Sleep 4500



WshShell.AppActivate oCalc.ProcessID
oCalc.Terminate()



Set oCalc = Nothing
Set WshShell = Nothing



jean-marc
Messages postés
4822
Date d'inscription
lundi 11 novembre 2002
Statut
Membre
Dernière intervention
15 novembre 2016
13
Bonsoir,
Merci à tous de votre participation constructive(programmation et relationel).
Violent Ken, est-il possible d'intercepter via le PID, que la calculatrice est ouverte(pour ne pas l'ouvrir plus d'une fois)?Sauf dans la cas ou l'utilisateur la ferme par son bouton unload, dans ce cas il peut l'ouvrir de nouveau.
Merci d'avance.
A+
Exploreur
Messages postés
4822
Date d'inscription
lundi 11 novembre 2002
Statut
Membre
Dernière intervention
15 novembre 2016
13
Violent Ken >> Ben...Franchement...Ton code, ta façon de l'expliquer >>> Parfait
Il me tarde le jour ou je sortitai du niveau débutant, et peut-être avoir le niveau de certains, faut savoir reconnaître les qualités des gens que l'on a en face de soit(pour ma part).
Merci encore.
A+
Exploreur
BON REVEILLON ET BONNE ANNEE EN AVANCE
Messages postés
1812
Date d'inscription
mardi 31 mai 2005
Statut
Membre
Dernière intervention
26 octobre 2010
1
Violent Ken

De rien, content d'avoir pu t'aider ;)
Et merci pour le compliment ^_-

@+ et bonnes fêtes à tous ^^
Messages postés
4822
Date d'inscription
lundi 11 novembre 2002
Statut
Membre
Dernière intervention
15 novembre 2016
13
Bonsoir Violent Ken,
J'ai bien regardé ton code, mais pour être honnet avec toi je comprend pas trop...
J'ai essayer de faire la même chose avec outlook, ben...cela répond pas de la même manière, donc j'ai repris ton code comme cela :

'Gestion erreur
 On Error GoTo err


'***Code de Violent ken *** relance outlook si pas présente
 If LCase$(Right$(GetPathFromPID(PID), 9)) <> "C:\Program Files\Outlook Express\msimn.exe" Then
    PID = Shell("C:\Program Files\Outlook Express\msimn.exe /mailurl:mailto:Exploreur13@hotmail.fr?subject=Demande informations sur X-Trem")
    GoTo sort
    Else
    MessageBox Me.hwnd, "La calculatrice est déjà ouverte !!!", "Information utilisateur", vbOKOnly + vbExclamation
    GoTo sort
 End If
 
err:
     MessageBox Me.hwnd, err.Description, "Information utilisateur", vbOKOnly + vbExclamation
     Exit Sub


sort:

Cela lance bien outlook, mais je peux tout de même le relancer plusieur fois!!!Comme je l'ai dit plus haut, je n'y comprend pas trop!!!

Merci d'avance si tu veux bien m'aider, et merci de tout de même si tu n'as pas le temps ou ne veux pas , je comprendrai.
A+
Exploreur
Messages postés
4822
Date d'inscription
lundi 11 novembre 2002
Statut
Membre
Dernière intervention
15 novembre 2016
13
Désolé pour le copier/coller.
Mes excuses
A+
Exploreur
Messages postés
1812
Date d'inscription
mardi 31 mai 2005
Statut
Membre
Dernière intervention
26 octobre 2010
1
Violent Ken

Salut, alors çà vient de cette ligne :

If LCase$(Right$(GetPathFromPID(PID), 9)) <> "C:\Program Files\Outlook Express\msimn.exe"

Reprenons la ligne de code que j'avais donnée :
If LCase$(Right$(GetPathFromPID(PID), 9)) <> "\calc.exe" Then PID = Shell("calc.exe")

Que fait-elle ?
> Lcase$() transforme en minuscules
> Right$(string,9) prend les 9 lettres de droite de la string
> GetPathFromPID(PID) renvoie le path (le chemin) en string
Donc on prennais les 9 lettres de droites (converties en minuscule si jamais la calculatrice s'appelle CaLc.EXe) et on comparait à "\calc.exe", qui fait 9 lettres.

J'ai fait le choix de faire un Right$() pour ne prendre que le nom du fichier (sans le chemin), cela comporte un avantage : si l'utilisateur a son Windows sur le lecteur D:\, le path en brut "C:\Windows\...." ne marcherait pas. Mais aussi un inconvénient, si un fichier s'appelle aussi calc.exe mais n'est pas situé dans \Windows\, on pourrait confondre avec la calculatrice de Windows.

Pour en revenir à ton code, 2 choix :

1) on prend le chemin (path) donc pas de Right$(), ce qui donne :
If LCase$(GetPathFromPID(PID)) <> "c:\program files\outlook express\msimn.exe"
2) on prend juste le nom du fichier (sans le path), donc un Right$(), ce qui donne :
If LCase$(Right$(GetPathFromPID(PID), 10)) <> "\msimn.exe"

Voilà, c'est déjà mieux ainsi, essaye pour voir si çà marche !
@+
Messages postés
4822
Date d'inscription
lundi 11 novembre 2002
Statut
Membre
Dernière intervention
15 novembre 2016
13
Bonsoir Violent_Ken,
Tu dois peut-être penser que je suis une débi..Tes explications sont très détaillées et j'aprécie beaucoup(La prochaine fois je ferai F1 et je réfléchirai un peu + au lieu de poser des questions un peu....).
Cela m'apprendra.
Merci énormément de m'avoir répondu, je vais mettre tout cela en oeuvre demain dans le code.Et surtout bosser encore un peu plus ton code avec tes explications.Encore délosé.
A+
Exploreur