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

  FORUM HardWare.fr
  Programmation

  [Borland C++ builder] Redirection sdtout

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[Borland C++ builder] Redirection sdtout

n°37458
Bruce
Music 4 your ears!
Posté le 06-06-2001 à 17:18:22  profilanswer
 

J'ai trouvé comment rediriger stdout
quasiment comme je le voulais (Je suis sous
Borland c++ 4.0)
Voilà, cela marche mais j'aimerais que cela marche légèrement différement...
En effet, lorsque je lance ma commande, je suis obligé d'attendre que cette
commande soit terminée pour que le résultat s'affiche dans mon Memo... De
plus, tous le temps de la commande, l'application est comme "bloquée",
impossible de déplacer la fenêtre par exemple...
Si qq un peu m'aider, cela serait vraiment sympa... Merci d'avance !
Voici mon code :
(précision, Rippack_RipFormBeta->Memo1 est le mémo dans lequel je sort,
filepos est ma ligne de commande)
 

Code :
  1. Rippack_RipFormBeta->Memo1->Clear();
  2. int FBreak;
  3. HANDLE hReadPipe;
  4. HANDLE hWritePipe;
  5. STARTUPINFO si;
  6. LPSECURITY_ATTRIBUTES lpsa = NULL;
  7. if(CreatePipe(&hReadPipe,&hWritePipe,lpsa,0))
  8. {
  9.   memset(&si, 0, sizeof(STARTUPINFO));
  10.   si.cb = sizeof(STARTUPINFO);
  11.   si.dwFlags = STARTF_USESHOWWINDOW |STARTF_USESTDHANDLES;
  12.   si.wShowWindow = SW_HIDE;
  13.   si.hStdOutput = hWritePipe;
  14.   si.hStdError = hWritePipe;
  15.   PROCESS_INFORMATION pi;
  16.   if(hWritePipe)
  17.   {
  18.     Rippack_RipFormBeta->Memo1->Lines->Add("Working..." );
  19.     Application->ProcessMessages();
  20.     if(CreateProcess(NULL,filepos.c_str(),NULL,NULL,TRUE,0,0,0,&si,&pi))
  21.     {
  22.       CloseHandle(pi.hThread);
  23.       WaitForSingleObject(pi.hProcess, 90000);
  24.       if(hReadPipe)
  25.       {
  26.         DWORD BytesRead; //unsigned long
  27.         char dest[4000];
  28.         bool RdLoopDone = false;
  29.         Rippack_RipFormBeta->Memo1->Clear();
  30.         FBreak = 1;
  31.         if(ExitCode) Screen->Cursor = crDefault;
  32.         while(!RdLoopDone)
  33.         {
  34.           memset(dest, 0, 4000);
  35.           if(ReadFile(hReadPipe, &dest, sizeof(dest), &BytesRead,
  36. NULL))
  37.           {
  38.             Rippack_RipFormBeta->Memo1->Lines->Add(String(dest));
  39.             if(BytesRead < 4000) RdLoopDone = true;
  40.             if(FBreak > 150) RdLoopDone = true;
  41.             FBreak++;
  42.             CloseHandle(hReadPipe);
  43.             CloseHandle(hWritePipe);
  44.             CloseHandle(pi.hProcess);
  45.           }
  46.         }
  47.       }
  48.     }
  49.   }
  50. }
 

[edit]--Message édité par bruce--[/edit]


---------------
A+++ Bruce - http://www.bheller.com
mood
Publicité
Posté le 06-06-2001 à 17:18:22  profilanswer
 

n°37466
JWhy
je peux plier (héhé)
Posté le 06-06-2001 à 17:33:08  profilanswer
 

oui, c'est normal... je me suis fait avoir de la meme facon...

Citation :


ReadFile returns when one of the following is true: a write operation completes on the write end of the pipe, the number of bytes requested has been read, or an error occurs.


c'est a dire que tant que tu n'ecris rien, ca ne "revient" pas et donc ton prog. est bloqué..
l'astuce (merci minicooler :jap: ) est d'utiliser l'API PeekNamedPipe pour savoir si il y a qqchose d'ecrit et si c'est le cas, utiliser ReadFile pour recuperer le contenu !


---------------
www.alliancefrancophone.org ... Home is where the heart is
n°37471
Bruce
Music 4 your ears!
Posté le 06-06-2001 à 17:38:05  profilanswer
 

Heu... tu n'aurrai pas un exemple de code qq part car je suis pas encore bien pro en prog... J'ai pompé ça sur un exemple fourni avec BC++ en adaptant à mes besoins...
 
Merci encore ! :)


---------------
A+++ Bruce - http://www.bheller.com
n°37476
JWhy
je peux plier (héhé)
Posté le 06-06-2001 à 18:00:34  profilanswer
 

beuh... j'fais du Delphi, moi...  mais je vais essayer de te trouver un bout de code relativement clair...


---------------
www.alliancefrancophone.org ... Home is where the heart is
n°37479
JWhy
je peux plier (héhé)
Posté le 06-06-2001 à 18:05:22  profilanswer
 

Code :
  1. procedure TProcess.ReadScreen;
  2. var
  3.   Buffer: array[0..255] of Char;
  4.   dwLeft, dwRead : DWORD;
  5. begin
  6. //  FillChar(Buffer, SizeOf(Buffer), 0);
  7.   dwLeft := 0;
  8.   dwRead := 0;
  9.   FLastLines := '';
  10.   PeekNamedPipe (hOutPipeRead, nil, 0, @dwRead, @dwLeft, nil);
  11.   // has anything been read?
  12.   if (dwLeft <> 0) then
  13.   begin
  14.     ReadFile(hOutPipeRead, Buffer, dwLeft, dwRead, nil);
  15.     // finish buffer to PChar
  16.     Buffer[dwRead] := #0;
  17.     // combine the buffer with the rest of the last run
  18.     FLastLines := Buffer;
  19.     FLines := FLines + Buffer ;
  20.   end;
  21. end;


---------------
www.alliancefrancophone.org ... Home is where the heart is
n°37483
Bruce
Music 4 your ears!
Posté le 06-06-2001 à 18:13:37  profilanswer
 

Heu... bon, je doit avouer avoir du mal à piger ta syntaxe... Le pascal est qd même légèrement différent... :)


---------------
A+++ Bruce - http://www.bheller.com
n°37487
antp
Super Administrateur
Champion des excuses bidons
Posté le 06-06-2001 à 18:26:10  profilanswer
 

pour éviter que ça bloque il faut faire régulièrement des Application->ProcessMessages(); c'est-à dire juste après le memo->lines->add.
Peut-être que ça résoudra l'autre problème en même temps...

 

[edit]--Message édité par antp--[/edit]


---------------
mes programmes ·· les voitures dans les films ·· apprenez à écrire
n°37488
Bruce
Music 4 your ears!
Posté le 06-06-2001 à 18:27:15  profilanswer
 

Pas con, je vais essayer.


---------------
A+++ Bruce - http://www.bheller.com
n°37489
antp
Super Administrateur
Champion des excuses bidons
Posté le 06-06-2001 à 18:29:08  profilanswer
 

si tu le met juste après le ->add il risque de pas le faire souvent pour les longues opérations
si tu le met dans la boucle en dehors du if c'est dangereux pcq ton appli risque de prendre trop de CPU pour rafraichir... il faut tester


---------------
mes programmes ·· les voitures dans les films ·· apprenez à écrire
n°37490
JWhy
je peux plier (héhé)
Posté le 06-06-2001 à 18:32:48  profilanswer
 

m'etonnerait que ca marche... c'est l'appel de l'API qui est bloquant... le ProcessMessage ne resoudra rien, je pense ...
 
sinon, regarde l'aide de l'API PeekNamedPipe, la declaration en C + le code Delphi devrait pouvoir t'aider a faire la conversion .


---------------
www.alliancefrancophone.org ... Home is where the heart is
mood
Publicité
Posté le 06-06-2001 à 18:32:48  profilanswer
 

n°37492
antp
Super Administrateur
Champion des excuses bidons
Posté le 06-06-2001 à 18:35:56  profilanswer
 

ha ouais c'est au WaitForSingleObject(pi.hProcess, 90000); qu'il bloque... j'avais pas vu.
le plus simple serait alors de le mettre dans un thread séparé je crois.


---------------
mes programmes ·· les voitures dans les films ·· apprenez à écrire
n°37493
antp
Super Administrateur
Champion des excuses bidons
Posté le 06-06-2001 à 18:39:58  profilanswer
 

ou alors:
while(!WaitForSingleObject(pi.hProcess, 1000))
{
  Application->ProcessMessages();
}
 
toutes les secondes il fait le processmessages.
je sais pas si c'est très bien comme solution.
et si le programme exécuté est calé il attend indéfiniment.


---------------
mes programmes ·· les voitures dans les films ·· apprenez à écrire
n°37494
robripper
Posté le 06-06-2001 à 18:40:03  profilanswer
 

antp a écrit a écrit :

ha ouais c'est au WaitForSingleObject(pi.hProcess, 90000); qu'il bloque... j'avais pas vu.
le plus simple serait alors de le mettre dans un thread séparé je crois.




 
un thread séparé, c le truc à faire en effet...

n°37495
Bruce
Music 4 your ears!
Posté le 06-06-2001 à 18:41:38  profilanswer
 

Heu... en Win32 j'ai du mal, un exemple de code ???


---------------
A+++ Bruce - http://www.bheller.com
n°37496
antp
Super Administrateur
Champion des excuses bidons
Posté le 06-06-2001 à 18:42:45  profilanswer
 

pourquoi en win32 ? y a des objets pour faire des threads dans C++builder, c'est plus simple à utiliser je crois.


---------------
mes programmes ·· les voitures dans les films ·· apprenez à écrire
n°37498
Bruce
Music 4 your ears!
Posté le 06-06-2001 à 18:44:29  profilanswer
 

Hummm... disons que je m'y connais mal ;)


---------------
A+++ Bruce - http://www.bheller.com
n°37499
robripper
Posté le 06-06-2001 à 18:45:55  profilanswer
 

bruce a écrit a écrit :

Hummm... disons que je m'y connais mal ;)




 
DWORD threadid;
HANDLE threadhandle;
 
...
threadhandle = CreateThread(NULL,1024,ma_fonction,NULL,CREATE_SUSPENDED,&threadid);
...
TerminateThread(threadhandle,0);
 
==================
 
 
DWORD WINAPI ma_fonction(LPVOID)
{
       EnterCriticalSection(&crit);
 
       // ... travail ...
 
       LeaveCriticalSection(&crit);
      return 0;
}

n°37501
antp
Super Administrateur
Champion des excuses bidons
Posté le 06-06-2001 à 18:48:08  profilanswer
 

robripper a écrit a écrit :

 
 
DWORD threadid;
HANDLE threadhandle;
 
...
threadhandle = CreateThread(NULL,1024,ma_fonction,NULL,CREATE_SUSPENDED,&threadid);
...
TerminateThread(threadhandle,0);
 




 
y a aussi la classe TThread.
Moi j'utiliserais celle-ci, ça a l'air plus simple :)

 

[edit]--Message édité par antp--[/edit]


---------------
mes programmes ·· les voitures dans les films ·· apprenez à écrire
n°37502
Bruce
Music 4 your ears!
Posté le 06-06-2001 à 18:48:11  profilanswer
 

Hu ?  :??:


---------------
A+++ Bruce - http://www.bheller.com
n°37503
robripper
Posté le 06-06-2001 à 18:48:26  profilanswer
 

Tu peux aussi modifier les priorités ...
 
SetThreadPriority(threadhandle,THREAD_PRIORITY_NORMAL);

n°37504
antp
Super Administrateur
Champion des excuses bidons
Posté le 06-06-2001 à 18:51:57  profilanswer
 

bruce a écrit a écrit :

Hu ?  :??:




 
prend l'aide de Builder à "TThread" je crois que c'est ce qu'il y aura de plus facile pour commencer...
sinon dans les exemples fournis il doit bien y en avoir un qui fait ça...


---------------
mes programmes ·· les voitures dans les films ·· apprenez à écrire
n°37505
robripper
Posté le 06-06-2001 à 18:54:53  profilanswer
 

Franchement moi j'utiliserais l'API c'est bien plus simple, je viens de jetter un oeil dans c++ builder  :D  
Attention, bientôt il va te faire utiliser Delphi, je connais bien antp  :hap:  :hap:

n°37506
antp
Super Administrateur
Champion des excuses bidons
Posté le 06-06-2001 à 18:58:52  profilanswer
 

robripper a écrit a écrit :

Franchement moi j'utiliserais l'API c'est bien plus simple, je viens de jetter un oeil dans c++ builder  :D  
Attention, bientôt il va te faire utiliser Delphi, je connais bien antp  :hap:  :hap:




 
ok pour l'API
avec Delphi le .exe serait moins gros :P


---------------
mes programmes ·· les voitures dans les films ·· apprenez à écrire
n°37507
robripper
Posté le 06-06-2001 à 18:59:25  profilanswer
 

Tu crées juste un thread, tu lui passes ta fonction en param (cell qui va faire tout le travail)... etc
 
En plus ici t'es pas obligé de section critique donc ...
 
DWORD WINAPI ma_fonction(LPVOID)
{
 
       // ... rippage, normalisation, etc etc ...  :sol:  
 
      return 0;
}

n°37509
Bruce
Music 4 your ears!
Posté le 06-06-2001 à 19:02:04  profilanswer
 

Honettement je suis un peu paumé, je vois pas trop ou vous voulez en venir (il faut dire que jes thread et moi... :)).


---------------
A+++ Bruce - http://www.bheller.com
n°37511
JWhy
je peux plier (héhé)
Posté le 06-06-2001 à 19:13:48  profilanswer
 

oui... je vois pas pourquoi vous lui parlez de threads ...
 
comme je te disais, le probleme vient de ReadFile qui est bloquant tant que rien n'est ecrit dans ton stdout... c'est a dire que si tu as un prog qui va ecrire un truc, attendre 5 secondes, ecrire un autre truc, readfile va bloquer ton appli pendant les 5 secondes ou le prog. n'ecrit rien dans le stdout...
 
 
il faut que tu remplaces le ReadFile bloquant:

Citation :


  if(ReadFile(hReadPipe, &dest, sizeof(dest), &BytesRead, NULL)) {
   [...]
  }


 
par un test pour savoir si il y a qqchose a lire et ensuite, si il y a qqchose, le lire (qui ne sera pas bloquant puisque tu vas lire exactement ce qu'il y a):

Citation :


  PeekNamedPipe (hOutPipeRead, nil, 0, @dwRead, @dwLeft, nil);  
 
  // has anything been read?  
  if (dwLeft <> 0) then  
  begin  
    ReadFile(hOutPipeRead, Buffer, dwLeft, dwRead, nil);  
    [...]
  end;


---------------
www.alliancefrancophone.org ... Home is where the heart is
n°37846
Bruce
Music 4 your ears!
Posté le 07-06-2001 à 16:21:24  profilanswer
 

un cht'i up car bon... je suis tj bloqué...


---------------
A+++ Bruce - http://www.bheller.com
mood
Publicité
Posté le   profilanswer
 


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

  [Borland C++ builder] Redirection sdtout

 

Sujets relatifs
Se connecter à un serveur MySQL a partir de Borland C++Redirection en php
passer des parametre avec borland c++ builder 5[Borland C++ 5.01] comment effacer un fichier ?
[C++ BORLAND] : cube[Javascript]= cibler deux frames avec un menu de redirection
C++ et Borland : OWLBonne redirection... j'en connais pas !
<meta> de redirection mais en page pleine comment ? 
Plus de sujets relatifs à : [Borland C++ builder] Redirection sdtout


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