Newsgroup: it.comp.lang.delphi
Titolo: Chiusura processi

Salve.
Avrei la necessità di chiudere alcuni processi che ho precedentemente
avviato dal mio programma, di cui conosco l'id del processo.
Ho visto che è possibile usare la funzione PostMessage() con il messaggio
WM_CLOSE; però è necessario sapere anche l'handle della finestra da
chiudere, che nel mio caso sarebbe la finestra "principale"; so che in
realtà in Windows non esiste una finestra principale, tuttavia per capirci
mi riferisco a quella form che in un'applicazione MDI contiene le child e
a quella che in una SDI con la sua chiusura provoca la fine del programma.
Sono riuscito anche a ottenere un elenco delle finestre appartenenti al
processo, però volendo evitare di salvarmi tutti i nomi delle classi delle
finestre "principali" dei processi che ho creato, come faccio a identificarle?
Grazie in anticipo.
Alessandro
--- posted by geoForum on 
http://www.delphiedintorni.it

finestre "principali" dei processi che ho creato, come faccio a identificarle?
Non puoi.  Non esiste una finestra che faccia chiudere il programma.
Non ti confondere con l'espressione "main form" di Delphi; sotto
Windows, come tu stesso dici, non esiste una "finestra principale". 
Esiste, invece, un thread primario, che č quello che, una volta
terminato, provoca la terminazione del processo.  Ma un processo puň
creare piů thread e un thread piů finestre.  Paradossalmente, non
esiste un modo sicuro per chiudere un processo esterno, che non sia
quello di killarlo brutalmente, usando TerminateProcess().
P.s.: la questione di cui stiamo parlando non attiene strettamente a
Delphi, spostati su it.comp.programmare.win32.

"Alessandro Vanni" <AlessandroVanni@REMOVE_ME_Interfree.it> ha scritto nel 
messaggio:
Aldilà di quanto correttamente detto da Andrea posso dirti che su sistemi NT 
uno dei modi più "eleganti" in cui mi son imbattuto è stata la chiamata a 
CreateRemoteThread() che invocava dall' interno del processo remoto una 
ExitProcess(). Preferisco di gran lunga questo alla TerminateProcess() che è 
da usare solo in casi *estremi* e che causa anche qualche problemuccio!
-- 
- Carlo - 

 CreateRemoteThread() 
In realtà il "code injection" CreateRemoteThread()+ExitProcess() non
rappresenta una via *sicura* per chiudere un processo.  Se non si conosce,
infatti, lo stato dei lock delle risorse interne da parte del/dei thread
dell'applicazione da chiudere, si può incorrere in uno stallo (di fatto,
CRT() rende qualsiasi applicazione multi-thread con tutti i problemi
derivanti, quali i deadlock).  In questi casi è sicuramente meglio
chiamare TerminateProcess() (come peraltro sottolineato nel PSDK stesso)
e, in ogni caso, se si vuol essere sicuri al 100% che il processo venga
terminato.
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 terminato.
Sul fatto che TerminateProcess() sia la via più sicura non c'è alcun dubbio. 
Solo proponevo una terminazione in stile Task Manager: se proprio il 
processo remoto non termina allora invoca TerminateProcess().
-- 
- Carlo - 

 processo remoto non termina allora invoca TerminateProcess().
Il Task Manager lavora con un sistema diverso, difatti utilizza un
time-out con la chiamata SendMessageTimeout, usando WM_NULL come
messaggio.  Dopo 5 secondi di time-out, il processo "non risponde" e
quindi viene killato.


quindi viene killato.
Grazie per le risposte.
Mi servirebbe appunto un qualcosa come il TaskManager di Windows in si può
chiudere qualsiasi applicazione permettendo a quest'ultima di chiudersi
come se fosse l'utente a chiuderla, infatti deve essere eseguito il codice
che ho inserito negli eventi "CloseQuery" delle form appartenenti ai
processi che devo chiudere.
P.S.: come suggerito da Andrea Laforgia ho riproposto il problema anche su
it.comp.programmare.win32.


processi che devo chiudere.
Devi distinguere: il TM ha due visualizzazioni: la lista delle
"operazioni" (pannellino "Applicazioni") e la lista dei nomi immagine
dei processi (pannellino "Processi").  La prima elenca tutte le
top-level window, quindi terminando un'operazione non fai altro che
chiudere la t-l w in modo pulito (WM_CLOSE per intenderci).  Quando
termini un processo, invece, viene invocato il brutale
TerminateProcess() sull'istanza del processo. 


Mi servirebbe la chiusura che il TM fa' dal tab "Applicazioni", però come
faccio a trovare la top level window che chiude l'applicazione tra quelle
che trova la funzione EnumWindows, che elenca tutte le top level window?
Alessandro


faccio a trovare la top level window che chiude l'applicazione
Come già detto: non puoi.

Come già detto: non puoi.
Come fa' allora il Task Manager a chiudere l'applicazione in modo pulito?


Come fa' allora il Task Manager a chiudere l'applicazione in modo pulito?
Ti è stato già spiegato il meccanismo in questo stesso thread.  Perché
non leggi ?

non leggi ?
Probabilmente c'è qualcosa che non capisco, che non mi permette di trovare
la risposta. Riporto le parti che mi sembrano possano rispondere alla mia
domanda:
"Esiste, invece, un thread primario, che è quello che, una volta
terminato, provoca la terminazione del processo."
"Il Task Manager lavora con un sistema diverso, difatti utilizza un
time-out con la chiamata SendMessageTimeout, usando WM_NULL come
messaggio.  Dopo 5 secondi di time-out, il processo "non risponde" e
quindi viene killato."
"il TM ha due visualizzazioni: la lista delle
"operazioni" (pannellino "Applicazioni") e la lista dei nomi immagine
dei processi (pannellino "Processi").  La prima elenca tutte le elenca
tutte le top-level window, quindi terminando un'operazione non fai altro
che chiudere la t-l w in modo pulito (WM_CLOSE per intenderci)."
La SendMessageTimeout() invia il messaggio alla finestra con l'handle
specificato, però io tramite la EnumWindows trovo più top level window
appartenenti allo stesso processo quindi non so quale handle passargli: il
processo che devo terminare è un'applicazione MDI.
Il TM riporta tutte le top level window di un processo, però nel mio caso
il TM mi fa' vedere una sola finestra, mentre come già detto l'EnumWindows
trova più finestre e non riesco a trovare quella da terminare: perché c'è
questa differenza tra il Task Manager e EnumWindows.
Ho capito che per terminare un processo bisogna terminare il thread
principale, però non riesco a identificarlo.
Sicuramente c'è qualcosa che non ho capito, però non riesco a capire quale.



Up.
