Newsgroup: it.comp.lang.c++
Titolo: Gestione Processi con WIN32

ciao
vorrei sapere quali sono le funzioni api/32 (visual c++ 6)
che permettono di:
  - lanciare un programma conoscendo il suo pid;
  - verificare continuamente se quel programma e' uscito o no.
Grazie.
Luca

  - lanciare un programma conoscendo il suo pid;
Il pid viene assegnato al momento in cui un processo viene
creato e in generale cambia ogni qual volta il processo
viene ricreato!
Ergo, un programma che deve ancora essere lanciato in esecuzione
(crendone il relativo processo) non ha pid!
Paolo
-----------------------------------------------------------------
  Paolo Marotta
  Computer Science, University of Pisa
  home:   
http://www.cli.di.unipi.it/~marotta
-----------------------------------------------------------------

  - verificare continuamente se quel programma e' uscito o no.
GetExitCodeProcess() ritorna STILL_ACTIVE se il processo non e' 
ancora terminato, e informazioni sulla terminazione se lo e'.
Per inciso, usarle direttamente significa di solito fare busy 
waiting. Se non hai il controllo del codice del processo chiamato, 
un approccio migliore, anche se un filo piu' complesso, e' 
incapsulare il tuo processo in una classe di cui hai il controllo; e 
fare in modo che questa invii un segnale di terminazione al processo 
padre quando il processo incapsulato e' finito. 
La classe wrapper sta di solito in un thread separato - e ti serve 
una gestione asincrona dei segnali (quindi un occhio alla 
sincronizzazione e alle regioni critiche).
Se hai tempo, anche se e' per java e non per C++, puoi dare 
un'occhiata alla guida del mio listener framework a 
http://space.tin.it/computer/csadun/software/lf/guide.html
 per una 
breve panoramica dell'argomento "segnali asincroni" (ovviamente, 
tralascia i dettagli sull'implementazione java :).
Non saprei se esiste la possibilita' di fare una join() direttamente 
come sotto unix, ma non credo.
-- 
God is Real, unless declared Integer.


Per verificare se un processo e' ancora attivo si puo' usare anche il
frammento di codice che riporto sotto.
Mi era servito per avviare un applicativo ad intervalli regolari, ma con
l'intervallo che doveva intercorrere tra la chiusura e il successivo
riavvio. E l'applicativo non aveva tempi regolari, ma dipendeva dai dati
che, nel frattempo, erano stati caricati.
Tra l'altro l'applicativo era un programma dos.
Ciao
Nazzareno
P.S. E' un po' OT qui, dovrebbe essere postato su it.comp.programmare.win32
// -------------------------------------------
void CRunByTimeDlg::runExec()
{
if(!idTimer)
  return;
KillTimer(idTimer);
int sw;
switch(Cfg.howStart) {
  case RUN_HIDE:
   sw = SW_HIDE;
   break;
  case RUN_ICON:
   sw = SW_SHOWMINNOACTIVE;
   break;
  default:
   sw = SW_SHOWNA;
   break;
  }
STARTUPINFO stI;
ZeroMemory(&stI, sizeof(stI));
stI.cb = sizeof(stI);
stI.dwFlags = STARTF_USESHOWWINDOW;
stI.wShowWindow = sw;
PROCESS_INFORMATION pI;
ZeroMemory(&pI, sizeof(pI));
if(!CreateProcess(NULL, Cfg.exec, 0, 0, 0,
     CREATE_NEW_CONSOLE |
     NORMAL_PRIORITY_CLASS, 0, 0,
     &stI, &pI))
  MessageBox("Errore");
else {
#if 0
  // cosě č bloccante, finche' il processo non si chiude il programma
  // č disabilitato, a meno di inserirlo in un thread separato
  WaitForSingleObject(pI.hProcess, INFINITE);
#else
#define MY_TIMEOUT 1000
  // qui invece attende un timeout di un secondo e poi processa
  // gli eventuali messaggi in coda
  while (true)
   if(WAIT_OBJECT_0 == WaitForSingleObject(pI.hProcess, MY_TIMEOUT))
    break;
   MSG msg;
   while ( ::PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
        if (!IsDialogMessage( &msg )  )
            TranslateMessage(&msg);
      DispatchMessage(&msg);
     }
    }
   }
#endif
  CloseHandle(pI.hProcess);
  CloseHandle(pI.hThread);
  }
SetTimer(idTimer = 1, Cfg.timer * (Cfg::eMinute == Cfg.whatTime ? 60 : 1) *
1000, 0);
}