Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
2498 connectés 

  FORUM HardWare.fr
  Programmation
  C++

  [C++] Exécution d'un programme dos [les bizarreries de windows]

 


 Mot :   Pseudo :  
 
 Page :   1  2
Page Précédente
Auteur Sujet :

[C++] Exécution d'un programme dos [les bizarreries de windows]

n°179722
antsite
Je me souviens
Posté le 22-07-2002 à 09:21:20  profilanswer
 

Via la fonction ShellExecute je lance un programme dos mais le problème c'est que ce programme dos ne se ferme pas automatiquement à la fin du programme : il ya le message bien connu Microsoft Popup windows Presser Ctrl+C pour fermer et retourner sous windows. J'aimerais bien éviter ce message. Il est possible de le faire en cochant la case "Fermer en quittant" dans les propriétés mais comment le faire en C++ ?
Avez vous une idée pour fermer cette fenêtre dos sans attendre le Ctrl-C ?
merci
 ANT


Message édité par antsite le 22-07-2002 à 09:28:15
mood
Publicité
Posté le 22-07-2002 à 09:21:20  profilanswer
 

n°179808
Ace17
Posté le 22-07-2002 à 11:21:44  profilanswer
 

j'ai pas la solution mais ca m'interesse donc ..... up

n°179812
antsite
Je me souviens
Posté le 22-07-2002 à 11:25:18  profilanswer
 

J'ai trouvé pas mal de trucs dans msdn mais rien n'y fait...
 
GenerateConsoleCtrlEvent -> ça devrait être ça mais je n'ai pas réussi à faire marcher cette fonction, elle me renvoie toujours une erreur. Même avec cette fonction SetConsoleCtrlHandler qui active bien le Ctrl-C...

n°179814
El_gringo
Posté le 22-07-2002 à 11:27:01  profilanswer
 

Bah, t'as qu'a, une fois que le batch (ou autre) est fini, envoyer un WM_CLOSE à la fenêtre...
non !?

n°179817
Ace17
Posté le 22-07-2002 à 11:28:35  profilanswer
 

Dans quel cas windows te demande d'appuyer sur Ctrl+C? comment cela se fait-il?

n°179833
antsite
Je me souviens
Posté le 22-07-2002 à 11:40:47  profilanswer
 

Je m'étais dit qu'en utilisant CreateProcess au lieu de ShellExecute on pourrait contourner le problème avec ça :
 
WaitForInputIdle(pinfo.hProcess,INFINITE);
GetExitCodeProcess(pinfo.hProcess,&ecode);
ExitProcess(ecode);
 
mais je ne sais pas pourquoi ce code me ferme mon app et non le processus lancé  :pt1cable:  
Pourtant dans createprocess j'ai mis false à inheritance...
 
De plus je n'arrive pas à fermer la console : SendMessage((HWND)pinfo.hProcess,WM_CLOSE,0,0); ne fonctionne pas (WM_DESTROY) non plus.
 
J'ai ce message lorsque je quitte une app dos lancée sous windows sans avoir coché l'option "Fermer en quittant" dans les propritétés du prog

n°179844
LetoII
Le dormeur doit se réveiller
Posté le 22-07-2002 à 11:51:02  profilanswer
 

ExitProcess quitte le process dans lequel elle est exécutée.
 
Utilise terminateProcess ou bien envoie le ctrl-C à ton prog.


---------------
Le Tyran
n°179848
El_gringo
Posté le 22-07-2002 à 11:55:13  profilanswer
 

letoII a écrit a écrit :

ExitProcess quitte le process dans lequel elle est exécutée.
 
Utilise terminateProcess ou bien envoie le ctrl-C à ton prog.




 
envoyer Ctrl-C, ou, plus simple, envoyer WM_CLOSE.
C plus propre qu'un terminate process...

n°179850
LetoII
Le dormeur doit se réveiller
Posté le 22-07-2002 à 11:57:30  profilanswer
 

el_gringo a écrit a écrit :

 
 
envoyer Ctrl-C, ou, plus simple, envoyer WM_CLOSE.
C plus propre qu'un terminate process...




 
tout à fait d'accord


---------------
Le Tyran
n°179865
antsite
Je me souviens
Posté le 22-07-2002 à 12:10:20  profilanswer
 

C'est sur mais le problème c'est que je ne sais pas comment récupérer le HWND du process créé. J'ai essayé de caster la HANDLE hProcess mais ça ne marche pas, ça ne doit pas être le hwnd de la console.
J'ai pas XP donc je peux faire une croix sur GetConsoleWindow()...
 
En plus le code suivant ne marche pas, je pige que dale  :ouch:  
GetExitCodeProcess(pinfo.hProcess,&ecode);
TerminateProcess(pinfo.hProcess,ecode);


Message édité par antsite le 22-07-2002 à 12:16:15
mood
Publicité
Posté le 22-07-2002 à 12:10:20  profilanswer
 

n°179880
Harkonnen
Modérateur
Un modo pour les bannir tous
Posté le 22-07-2002 à 12:30:34  profilanswer
 

Tu fais un EnumWindows pour trouver le hWnd de la console, puis tu lui balance un WM_CLOSE, et roulez jeunesse :)


---------------
J'ai un string dans l'array (Paris Hilton)
n°179882
El_gringo
Posté le 22-07-2002 à 12:30:46  profilanswer
 

antsite a écrit a écrit :

C'est sur mais le problème c'est que je ne sais pas comment récupérer le HWND du process créé. J'ai essayé de caster la HANDLE hProcess mais ça ne marche pas, ça ne doit pas être le hwnd de la console.
J'ai pas XP donc je peux faire une croix sur GetConsoleWindow()...
 
En plus le code suivant ne marche pas, je pige que dale  :ouch:  
GetExitCodeProcess(pinfo.hProcess,&ecode);
TerminateProcess(pinfo.hProcess,ecode);




 
Ha non, caster le hProcess, ça va pas du tout !
Un fenêtre, c pas la même chose qu'un process, tu l'sais bien qd même. non !?
tu peux utiliser ça :
 

Code :
  1. //------------------------------------------------------------------------------------------------------------
  2. // Termine une application Win32 "proprement"
  3. // Paramètre : Handler du process à killer et temps d'attente avec de terminer le processus "brutalement"
  4. // Retour    : BOOL, TRUE si kill réussi
  5. //       FALSE si raté
  6. //------------------------------------------------------------------------------------------------------------
  7. BOOL CLanSession::TerminateApp(DWORD _dwPID, DWORD _dwTimeOut)
  8. {
  9. HANDLE hProc;
  10. DWORD  dwRetour;
  11. hProc = OpenProcess(SYNCHRONIZE|PROCESS_TERMINATE, FALSE, _dwPID);
  12. if (hProc == NULL)
  13.  return FALSE;
  14. EnumWindows ((WNDENUMPROC) TerminateAppEnum, (LPARAM) _dwPID);
  15. if (WaitForSingleObject(hProc, _dwTimeOut) != WAIT_OBJECT_0)
  16.  dwRetour = TerminateProcess (hProc, 0) ? TRUE:FALSE;
  17. else
  18.  dwRetour = TRUE;
  19. CloseHandle (hProc);
  20. return dwRetour;
  21. }
  22. //-----------------------------------------------------------------------------------------------------------
  23. // poste un message WM_CLOSE à toutes les fenêtres dont le PID concorde avec celui du process
  24. //-----------------------------------------------------------------------------------------------------------
  25. BOOL CALLBACK TerminateAppEnum (HWND _hWnd, LPARAM _lParam)
  26. {
  27. DWORD dwID;
  28. GetWindowThreadProcessId(_hWnd, &dwID);
  29. if (dwID == (DWORD)_lParam)
  30.  PostMessage(_hWnd, WM_CLOSE, 0, 0);
  31. return TRUE;
  32. }


 
(c du copier/coller en brute, j'éspère que ça va être lisible)


Message édité par El_gringo le 22-07-2002 à 12:32:31
n°179884
El_gringo
Posté le 22-07-2002 à 12:33:11  profilanswer
 

...c un extrait du mon 1er prog C(++ ?), soyez indulgents !

n°179904
antsite
Je me souviens
Posté le 22-07-2002 à 13:32:18  profilanswer
 

Merci beaucoup à tous les 2, ça marche très bien.
Seulement un dernier petit ennui : si on veut fermer proprement la console via un message WM_CLOSE, il apparait une boîte de dialogue disant un truc du genre : Etes vous sur de vouloir fermer la fenêtre... Infos non sauvegardées... Comment eviter ce msg ? WM_DESTROY fonctionne encore moins, il n'essaye même pas de fermer la console (pas de popup de confirmation).

n°179908
JPA
Posté le 22-07-2002 à 13:41:26  profilanswer
 

Je vais me mêler de ce qui ne me regarde pas, mais n'aurait-il pas été plus simple de créer dans le progr C un raccourci vers l'exécutable "DOS", raccourci comportant les paramètres pour fermer la fenêtre en quittant, puis de lancer le raccourci ?
A+

n°179910
antsite
Je me souviens
Posté le 22-07-2002 à 13:44:34  profilanswer
 

Tout à fait mais j'ignore comment faire ce raccourci avec le paramètre voulu !

n°179915
antsite
Je me souviens
Posté le 22-07-2002 à 13:56:28  profilanswer
 

Pour reprendre l'idée de WM_CLOSE je pensais que plus simplement pour éviter la popup il faudrait lui envoyer ce qu'il demande à savoir Ctrl+C. Seulement je n'y arrive pas, je comprends pas la msdn. Comment envoyer Ctrl+C ?
WM_KEYDOWN
wParam: 'c'
lParam: ???? je comprends pas comment ça marche ce lParam, comment lui dire que Ctrl est pressée ?

n°179917
Harkonnen
Modérateur
Un modo pour les bannir tous
Posté le 22-07-2002 à 14:04:19  profilanswer
 

c'est un champ de bits. le bit 29 te permet de dire si une touche étendue est enfoncée ou pas (1 = pressée).
 
verifie le msdn sur WM_KEYDOWN pour plus d'infos. mais moi je te conseillerais plutot WM_KEYUP, car il peut se produire plusieurs KEYDOWN avant un KEYUP
 
j'ai jamais compris d'ailleurs pq tout le monde utilisait WM_KEYDOWN ! il me semble que WM_KEYUP est bien plus significatif puisqu'il se produit une fois que la touche a été relachée


---------------
J'ai un string dans l'array (Paris Hilton)
n°179921
antsite
Je me souviens
Posté le 22-07-2002 à 14:07:18  profilanswer
 

Tu peux me filer un bout de code car je ne sais pas du tout manier les champs de bits  :(

n°179945
Harkonnen
Modérateur
Un modo pour les bannir tous
Posté le 22-07-2002 à 14:21:12  profilanswer
 

// on appuie d'abord sur ctrl-C
PostMessage(hWnd, WM_KEYDOWN, VK_CONTROL, 0x00010001); // CTRL
PostMessage(hWnd, WM_KEYDOWN, (WPARAM)0x43, 0x00010001); // C
 
// puis on relache ctrl-C
PostMessage(hWnd, WM_KEYUP, VK_CONTROL, 0x00010001); // CTRL
PostMessage(hWnd, WM_KEYUP, (WPARAM)0x43, 0x00010001); // C
 
 
 


---------------
J'ai un string dans l'array (Paris Hilton)
n°179960
El_gringo
Posté le 22-07-2002 à 14:38:04  profilanswer
 

Harkonnen a écrit a écrit :

// on appuie d'abord sur ctrl-C
PostMessage(hWnd, WM_KEYDOWN, VK_CONTROL, 0x00010001); // CTRL
PostMessage(hWnd, WM_KEYDOWN, (WPARAM)0x43, 0x00010001); // C
 
// puis on relache ctrl-C
PostMessage(hWnd, WM_KEYUP, VK_CONTROL, 0x00010001); // CTRL
PostMessage(hWnd, WM_KEYUP, (WPARAM)0x43, 0x00010001); // C




 
j'comprend pas bien ça... moi j'aurai converti le LPARAM en décimal
C'est de la Hexa que tu donnes là !?

n°179962
antsite
Je me souviens
Posté le 22-07-2002 à 14:43:06  profilanswer
 

Merci pour ce cours sur le champ de bits, ça devient plus clair désormais !
Mais alors quel bug !!! Je met ce code dans la fonction callback à la place de WM_CLOSE :
 
PostMessage(hWnd,WM_KEYDOWN,VK_CONTROL,128L);
PostMessage(hWnd,WM_KEYDOWN,'c',0L);
 
ou :
 
PostMessage(hWnd,WM_KEYUP,VK_CONTROL,128L);
PostMessage(hWnd,WM_KEYUP,'c',0L);
 
ou les 2, et là y a le PC qui se met à beeper comme un fou et il faut faire un reset !
Enfait la console se bloque alors qu'elle est en train d'écrire le message disant qu'il faut appuyer sur Ctrl-C pour fermer donc peut être que WM_KEYUP/DOWN est trop tôt ?

n°179964
Harkonnen
Modérateur
Un modo pour les bannir tous
Posté le 22-07-2002 à 14:46:46  profilanswer
 

il faut mettre les 2, WM_KEYDOWN et WM_KEYUP ! tu ne peux pas en mettre qu'un !
si tu ne met que WM_KEYDOWN, ça veut dire que tu ne relaches jamais tes touches, donc le buffer se remplit et tu obtiens les effets indésirables que tu me décris


---------------
J'ai un string dans l'array (Paris Hilton)
n°179965
Harkonnen
Modérateur
Un modo pour les bannir tous
Posté le 22-07-2002 à 14:47:22  profilanswer
 

el_gringo a écrit a écrit :

 
 
j'comprend pas bien ça... moi j'aurai converti le LPARAM en décimal
C'est de la Hexa que tu donnes là !?




Oui, c de l'hexa, peu importe que ce soit de l'hexa, décimal ou binaire


---------------
J'ai un string dans l'array (Paris Hilton)
n°179969
antsite
Je me souviens
Posté le 22-07-2002 à 14:55:53  profilanswer
 

PostMessage(hWnd,WM_KEYDOWN,VK_CONTROL,0x00010001);
PostMessage(hWnd,WM_KEYDOWN,(WPARAM)0x43,0x00010001);
 
PostMessage(hWnd,WM_KEYUP,VK_CONTROL,0x00010001);
PostMessage(hWnd,WM_KEYUP,(WPARAM)0x43,0x00010001);
 
ce code ne marche pas mais ça plante pas. Par contre toi Harko tu met 0x00010001 aussi bien à Ctrl qu'à C est-ce normal ? Alors pourquoi El Gringo met 0 & 128 et non pas les 2 mêmes nombres ?

n°179983
Harkonnen
Modérateur
Un modo pour les bannir tous
Posté le 22-07-2002 à 15:08:37  profilanswer
 

Je me suis planté dans les scancodes et les virual keys. essaie plutot ceci :
 
PostMessage(hwnd, WM_KEYDOWN, VK_CONTROL, 0x001D0001 ) ;
PostMessage(hwnd, WM_KEYDOWN, (WPARAM)0x43, 0x00170001 ) ;
PostMessage(hwnd, WM_KEYUP, (WPARAM)0x43, 0xC0170001 ) ;
PostMessage(hwnd, WM_KEYUP, VK_CONTROL, 0xC01D0001 ) ;


---------------
J'ai un string dans l'array (Paris Hilton)
n°179989
antsite
Je me souviens
Posté le 22-07-2002 à 15:13:11  profilanswer
 

Ca ne marche pas ! (mais ça ne plante plus c déjà ça)

n°180012
Harkonnen
Modérateur
Un modo pour les bannir tous
Posté le 22-07-2002 à 15:34:00  profilanswer
 

:heink:  
Essaie de voir avec Spy++ si la console reçoit bien les messages.
 
Je m'explique sur la signification de lParam :
 
0x001D 0001
les 2 octets de poids faibles indiquent le nombre de répétitions (ici 1)
les bits 16 à 23 indiquent le scancode de la touche CTRL (1D)
les autres bits sont inutiles pour un KEYDOWN
 
0xC01D 0001
les bits 30 et 31 sont mis à 1 (C0) :
- bit 30 = état précédent de la touche avant envoi du message (1 = enfoncée, ce qui était le cas)
- bit 31 = état de transition de la touche (1 = touche relachée, ce qui est le cas ici)
 
donc, ça devrait marcher.... j'ai pas testé, mais je vois pas ce qui peut merder !


---------------
J'ai un string dans l'array (Paris Hilton)
n°180014
Harkonnen
Modérateur
Un modo pour les bannir tous
Posté le 22-07-2002 à 15:36:45  profilanswer
 

tiens, j'ai une idée : tu utilises Spy++ sur la console. tu tapes CTRL-C pour la fermer, puis tu observes les paramètres correspondants. tu envoies ensuite un WM_KEYDOWN et WM_KEYUP avec ces paramètres


---------------
J'ai un string dans l'array (Paris Hilton)
n°180045
antsite
Je me souviens
Posté le 22-07-2002 à 15:56:35  profilanswer
 

Aucun message WM_KEYDOWN/UP envoyé, tu m'étonnes que ça ne marchait pas !
il y a ça d'intéressant (après c STYLECHANGING, ACTIVATE,...) :
00000E74 P message:0x0418 [User-defined:WM_USER+24] wParam:47180000 lParam:C7A14754
 
Comment faut-il réutiliser cela ? Directement en envoyant WM_USER+24, wParam & lParam ?

n°180054
Harkonnen
Modérateur
Un modo pour les bannir tous
Posté le 22-07-2002 à 16:02:58  profilanswer
 

non, surtout pas, ça n'a rien à voir avec WM_KEYxxxx
il faut savoir pourquoi la console ne récupère pas ces messages. es tu sur que le hWnd de la console est correct ?
 
utilise Spy++ pour visualiser le hWnd de la console, puis fais un MessageBox pour afficher le hWnd. compare les, et vois s'ils sont identiques


---------------
J'ai un string dans l'array (Paris Hilton)
n°180066
antsite
Je me souviens
Posté le 22-07-2002 à 16:11:28  profilanswer
 

Je crois qu'on c mal compris : le message que je t'ai donné dans le post précédent c'est ce que Spy++ reçoit quand je fais à la main Ctrl+C.
 
Sinon je ne vois pas comment comparer les hwnd. Comment faire, c quoi un hWnd, c'est pas un entier, c quoi ? Je vois pas quoi afficher dans la msgbox. Le hwnd dans spy++ c ce qui est appelé Window ?

n°180079
antsite
Je me souviens
Posté le 22-07-2002 à 16:26:20  profilanswer
 

Et puis j'y pense c sur que c le bon hWnd puisque le message WM_CLOSE marche (sauf qu'il y a cette foutue popup qui oblige à laisser tomber WM_CLOSE)

n°180094
Harkonnen
Modérateur
Un modo pour les bannir tous
Posté le 22-07-2002 à 16:36:58  profilanswer
 

peut etre que le hWnd de la popup est différent de celui de la console, ce qui ne m'étonnerait pas d'ailleurs, car la console est incapable d'afficher du graphisme.
 
utilise Spy++ sur le popup et la console, et voit si les hwnd sont différents


---------------
J'ai un string dans l'array (Paris Hilton)
n°180105
antsite
Je me souviens
Posté le 22-07-2002 à 16:43:00  profilanswer
 

En effet les hwnd sont différents. Lorsque que je veux voir les messages de la console et non de la popup de la console, voila le message me disant que c impossible... :
 
The specified window cannot be spied upon. Windows will not allow access to the message stream for this window.
 
De mieux en mieux lol...

n°180110
Harkonnen
Modérateur
Un modo pour les bannir tous
Posté le 22-07-2002 à 16:47:26  profilanswer
 

ben t'as plus qu'a faire un EnumWindows pour récuperer la fenetre popup, et envoyer ensuite les messages que je t'ai indiqués plus haut.
ça devrait le faire :)


---------------
J'ai un string dans l'array (Paris Hilton)
n°180121
antsite
Je me souviens
Posté le 22-07-2002 à 16:50:29  profilanswer
 

Ok merci.
Peux tu m'expliquer comment se servir des hWnd (les comparer). Comment vais-je faire avec mes enum windows pour savoir quelle est la bonne fenêtre ?

n°180132
antsite
Je me souviens
Posté le 22-07-2002 à 16:59:22  profilanswer
 

HWND h = ::FindWindow("ttyGrab","" ); ne marche pas, rien n'est trouvé. Pourtant la class de la console (et non la popup de la console) est bien ttyGrab d'après Spy++ et son title ""... :sweat:

n°180135
Harkonnen
Modérateur
Un modo pour les bannir tous
Posté le 22-07-2002 à 17:02:54  profilanswer
 

antsite a écrit a écrit :

Ok merci.
Peux tu m'expliquer comment se servir des hWnd (les comparer). Comment vais-je faire avec mes enum windows pour savoir quelle est la bonne fenêtre ?




tu as fait dans ton post suivant ce que je t'aurais siggéré :)


---------------
J'ai un string dans l'array (Paris Hilton)
n°180139
Harkonnen
Modérateur
Un modo pour les bannir tous
Posté le 22-07-2002 à 17:06:09  profilanswer
 

antsite a écrit a écrit :

HWND h = ::FindWindow("ttyGrab","" ); ne marche pas, rien n'est trouvé. Pourtant la class de la console (et non la popup de la console) est bien ttyGrab d'après Spy++ et son title ""... :sweat:  




et si tu renseignes également le second paramètre de FindWindow (le nom de la fenêtre), il ne te trouves rien ?


---------------
J'ai un string dans l'array (Paris Hilton)
mood
Publicité
Posté le   profilanswer
 

 Page :   1  2
Page Précédente

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

  [C++] Exécution d'un programme dos [les bizarreries de windows]

 

Sujets relatifs
VB5 + Windows 2000 = BUG...HELP !!! exécution d'un fichier batch sur 1 serveur distant
[Postgresql] version windows ?Ou peut on trouver des exemple de programme fait avec Access ?
Programme d'installationun programme pour creer des pages web en anim flash ?
Impossible d'installer Visual c++ 4 sous windows NT - URGENTFaire un appel système à un script ou un programme [RESOLU]
comment aboir un historique des demarrage et fin windows ?Mettre un pixel d'une certaine couleur en c++ avec Windows
Plus de sujets relatifs à : [C++] Exécution d'un programme dos [les bizarreries de windows]


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR