terminateprocess() boucle problème

terminateprocess() boucle problème - C++ - Programmation

Marsh Posté le 25-08-2011 à 17:10:31    

Bonjour,  
J'ai un petit soucis avec mon code que je n'arrive pas à résoudre.
Tout d'abord le but de mon code est de récupérer dans un fichier texte le chemin d'accès d'un fichier et l'exécute. Il vérifie ensuite toutes les x secondes si le chemin a changé.Si non il continu à exécuter le fichier ,si oui il ferme l'ancien fichier et exécute le nouveau.
Je suis arrivé avec de l'aide sur les forums à tout faire mais je n'arrive pas à fermer le premier fichier exécuté lorsque l'on doit exécuté le nouveau.
Ma boucle n'est pas parfaite je sais si quelqu'un pourrait m'aiguiller ou m'expliquer qq trucs ça serait gentil.
Mon code :

Code :
  1. int main()
  2. {
  3. string ligne1, ligne2;
  4. HANDLE hProcess;
  5.     UINT uExitCode;
  6. PROCESS_INFORMATION pi;
  7. STARTUPINFO si = {sizeof(si)};
  8. while(true)
  9. {
  10. ligne1=enTete("D:\\test.txt" );
  11. if(ligne2.compare(ligne1)!=0)
  12. {
  13.  string cmdline = (string("C:\\Program Files (x86)\\Microsoft Office\\Office14\\PPTVIEW.exe \"" ) + ligne1 + "\"" );
  14. if (!CreateProcess(0, (LPSTR)cmdline.c_str(), 0, 0, 0, CREATE_SUSPENDED, 0, 0, &si, &pi))
  15. break;
  16. ligne2=ligne1;
  17. ResumeThread(pi.hThread);
  18. CloseHandle(pi.hThread);
  19. Sleep(4000);
  20. TerminateProcess(pi.hProcess,0);
  21. CloseHandle(pi.hProcess);
  22. }
  23. Sleep(10000);
  24. }
  25. }


De plus il y a un truc déjà qui me dérange dans ma boucle infini (while(true)) comment se fait il qu'il execute la partie du code dans if(ligne2.compare(ligne1)!=0) alors que la condition n'est même pas remplit ?
Merci.
Cordialement,

Reply

Marsh Posté le 25-08-2011 à 17:10:31   

Reply

Marsh Posté le 25-08-2011 à 18:42:03    

Citation :

comment se fait il qu'il execute la partie du code dans if(ligne2.compare(ligne1)!=0) alors que la condition n'est même pas remplit ?

En clair, ça veut dire quoi "la condition n'est même pas remplie"?
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 25-08-2011 à 18:45:51    

bah en gros même si ligne2 est pareil que ligne1 il exécute quand même ce qui suit. Je sais pas si c'est très clair désolé je débute en prog

Reply

Marsh Posté le 26-08-2011 à 10:56:08    

S'il exécute le code, c'est surement que ligne1 et ligne 2 ne sont pas identiques. A toi de tester et de voir pourquoi.
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 26-08-2011 à 10:58:07    

Ok je vais voir merci déjà de m'avoir confirmé cela. Bonne journée

Reply

Marsh Posté le 26-08-2011 à 12:29:16    

Bonjour,
Y a que moi à trouver terminateprocess() hyper violent?
Pourquoi ne pas envoyer un ALT+F4 ou un WM_CLOSE programatiquement à l'application?


---------------
Seul Google le sait...
Reply

Marsh Posté le 26-08-2011 à 13:35:53    

Oui, ça devrait être ExitProcess à priori.
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 26-08-2011 à 16:18:49    

On fait comment pour envoyer un ALT+F4 ?

Reply

Marsh Posté le 26-08-2011 à 18:05:24    

Hello, je sais que j'arrive après après la bataille mais pour faire un truc propre il faudrait utiliser l'interface COM de powerpoint (enfin ça n'engage que moi), ce qui est assez chiant en C mais peut se faire assez simplement avec autoit.
J'ai bricolé ça rapide :

Code :
  1. Local $ppoint = ObjCreate("PowerPoint.Application" )
  2. Func OnExit()
  3.     $ppoint.Quit()
  4. EndFunc
  5. If Not IsObj($ppoint) Then
  6.     MsgBox(0, "Erreur", "Impossible de créer l'objet powerpoint" )
  7.     Exit
  8. Else
  9.     OnAutoItExitRegister("OnExit" )
  10. EndIf
  11. $ppoint.Visible = True
  12. Local $nomPresentation = FileReadLine("cfg.txt", 1)
  13. Local $presentation = $ppoint.Presentations.Open(@ScriptDir & "\" & $nomPresentation)
  14. While 1
  15.     $tmp = FileReadLine("cfg.txt", 1)
  16.     If $tmp <> $nomPresentation Then
  17.         $nomPresentation = $tmp
  18.         $presentation.Close()
  19.         $presentation = $ppoint.Presentations.Open(@ScriptDir & "\" & $nomPresentation)
  20.     EndIf
  21.     Sleep(1000)
  22. Wend


 
[edit] sinon la solution "barbare" marche aussi en autoit :

Code :
  1. Const $PPVIEW_EXE = "C:\Program Files\Microsoft Office\Office\Xlators\PPVIEW32.EXE"
  2. Local $nomPresentation = FileReadLine("cfg.txt", 1)
  3. Local $pid = Run($PPVIEW_EXE & ' "' & @ScriptDir & "\" & $nomPresentation & '"')
  4. While 1
  5.    $tmp = FileReadLine("cfg.txt", 1)
  6.    If $tmp <> $nomPresentation Then
  7.         $nomPresentation = $tmp
  8.         ProcessClose($pid)
  9.         $pid = Run($PPVIEW_EXE & ' "' & @ScriptDir & "\" & $nomPresentation & '"')
  10.     EndIf
  11.     Sleep(1000)
  12. WEnd


Message édité par SquiZZ le 26-08-2011 à 18:26:16
Reply

Marsh Posté le 26-08-2011 à 23:40:31    

gilou a écrit :

Oui, ça devrait être ExitProcess à priori.
A+,


non exitprocess termine le processus courant, pas un autre...
 
+1 pour l'automation mais est-elle dispo juste avec le viewer ou faut-il tout powerpoint?
 
sinon je tenterais le WM_CLOSE avec SendMessage -> http://msdn.microsoft.com/en-us/li [...] 85%29.aspx et http://msdn.microsoft.com/en-us/li [...] 85%29.aspx
ce qui donnerait grosso merdo
SendMessage(Findwindows(NULL, "nom de ta fenetre powerpoint?" ), WM_CLOSE, 0, 0);

Message cité 1 fois
Message édité par breizhbugs le 27-08-2011 à 14:48:09

---------------
Seul Google le sait...
Reply

Marsh Posté le 26-08-2011 à 23:40:31   

Reply

Marsh Posté le 27-08-2011 à 00:03:54    

Effectivement, pas sûr que l'on puisse faire de l'automation avec seulement le viewer.
D'un autre côté je suis pas sûr non plus que la fenêtre du viewer a un titre.
Il doit y avoir moyen de bricoler un truc à base de EnumWindows et GetWindowThreadProcessId pour récupérer la handle de la fenêtre
 
[edit]

Code :
  1. #include <windows.h>
  2. DWORD Start(LPSTR app)
  3. {
  4.     PROCESS_INFORMATION pi = {0};
  5.     STARTUPINFO si = {sizeof(si)};
  6.     if(!CreateProcess(NULL, app, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
  7.         return 0;
  8.     CloseHandle(pi.hProcess);
  9.     CloseHandle(pi.hThread);
  10.     return pi.dwThreadId;
  11. }
  12. BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
  13. {
  14.     if(GetWindowThreadProcessId(hwnd, NULL) == (DWORD)lParam)
  15.     {
  16.         PostMessage(hwnd, WM_CLOSE, 0, 0);
  17.         return FALSE; // arrêter l'énumération
  18.     }
  19.     return TRUE;
  20. }
  21. void Stop(DWORD tid)
  22. {
  23.     EnumWindows(EnumWindowsProc, tid);
  24. }
  25. int main()
  26. {
  27.     char app[] = "notepad.exe";
  28.     DWORD tid = Start(app);
  29.     Sleep(2000);
  30.     Stop(tid);
  31.     return 0;
  32. }


Ca a l'air de marcher (avec notepad en tout cas ;) )


Message édité par SquiZZ le 27-08-2011 à 01:13:19
Reply

Marsh Posté le 27-08-2011 à 09:36:51    

breizhbugs a écrit :


non exitprocess termine le processus courant, pas un autre...
 
+1 pour l'automation mais est-elle dispo juste avec le viewer ou faut-il tout powerpoint?
 
sinon je tenterais le WM_CLOSE avec SendMessage -> http://msdn.microsoft.com/en-us/li [...] 85%29.aspx et http://msdn.microsoft.com/en-us/li [...] 85%29.aspx
ce qui donnerait grosso merdo
SenMessage(Findwindows(NULL, "nom de ta fenetre powerpoint?" ), WM_CLOSE, 0, 0);

Euh oui, j'avais lu la doc trop vite pour exitprocess
Ici, puisqu'on à le threadId dans la structure pi, faire un PostThreadMessage avec WM_QUIT devrait coller, non?
Bref, un truc comme:
ResumeThread(pi.hThread);
PostThreadMessage(pi.dwThreadId, WM_QUIT, 0, 0);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
 
A+,


Message édité par gilou le 27-08-2011 à 09:48:15

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 27-08-2011 à 12:55:27    

Effectivement.
J'ai toujours été persuadé que PostThreadMessage ne marchait que pour les threads appartenant au processus lui même alors que rien ne l'indique dans la doc.

Reply

Marsh Posté le 27-08-2011 à 18:36:37    

Non, mais dans un cadre général, il y a peut-être une question de droits sous Vista et W7 pour qu'il accepte les messages d'un autre programme.
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 27-08-2011 à 19:29:15    

gilou a écrit :

Non, mais dans un cadre général, il y a peut-être une question de droits sous Vista et W7 pour qu'il accepte les messages d'un autre programme.
A+,


 
Ah ce propos:  
http://msdn.microsoft.com/en-us/li [...] 85%29.aspx
PostThreadMessage: When a message is blocked by UIPI the last error, retrieved with GetLastError, is set to 5 (access denied).
 
ainsi que:
http://blogs.msdn.com/b/vishalsi/a [...] vista.aspx


---------------
Seul Google le sait...
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed