PDA

Visualizza la versione completa : Chiudere ultimo programma aperto con c


Tarrion
03-06-2010, 12:29
salve a tutti, vorrei avere qualche dritta da voi esperti per sviluppare un programmino in c semplicissimo (spero): una volta eseguito deve solo chiudere il penultimo .exe che è stato aperto in task manager e poi terminarsi automaticamente.

che ne pensate, come si può fare? (considerate che non sono molto esperto, le mie conoscenze di c si limitano ad un corso di informatica alla facoltà di matematica)

grazie per ogni eventuale aiuto

linoma
03-06-2010, 12:54
e perche il penultimo?

Tarrion
03-06-2010, 13:08
allora, io gioco a un gioco online che può bloccarsi e ho uno script che in caso di blocco deve aprire un'altra istanza di questo gioco e necessariamente chiudere quella più vecchia (bloccata).

Lo script può aprire una nuova istanza, ma non può chiudere quella vecchia e quindi dovrebbe richiamare un programma esterno che la termini.

Il problema da risolvere è che le due istanze non hanno lo stesso nome, quindi ho pensato di fare un piccolo .exe che fa un check sul tempo di esecuzione di ognuna delle due e chiude quella attiva da piu tempo in questo modo:

-se l'istanza "nome_prima_istanza.exe" è aperta da più di x minuti, chiudila;
-se l'istanza "nome_seconda_istanza.exe" è aperta da più di x minuti, chiudila;

in questo modo ne viene chiusa solo una perché l'altra è aperta da soli pochi secondi.

se può essere utile io pensavo di usare il comando da console "taskkill" che ha come parametro anche cputime, ma come lo scrivo in c? Avete altre idee?

linoma
03-06-2010, 13:15
Forse potresti usare il visualbasicscript o il javascript da dos (cscript). Se non conosci il c. Il comando che dici offre molti filtri. Ti serve solo un programmino che lo richiami.

Tarrion
03-06-2010, 14:57
Beh, io preferirei c perché ormai ho parecchia familiarità.
In pratica mi servirebbe solo un programma in c che richiami il comando "taskkill" e che faccia anche quei controlli sul tempo di esecuzione, ma quali sono i comandi in c relativi a tali operazioni?
Potreste in caso postare un esempio di codice dal quale posso prendere spunto?

billiejoex
06-06-2010, 16:03
Originariamente inviato da Tarrion
allora, io gioco a un gioco online che può bloccarsi e ho uno script che in caso di blocco deve aprire un'altra istanza di questo gioco e necessariamente chiudere quella più vecchia (bloccata).

Lo script può aprire una nuova istanza, ma non può chiudere quella vecchia e quindi dovrebbe richiamare un programma esterno che la termini.

Il problema da risolvere è che le due istanze non hanno lo stesso nome, quindi ho pensato di fare un piccolo .exe che fa un check sul tempo di esecuzione di ognuna delle due e chiude quella attiva da piu tempo in questo modo:

-se l'istanza "nome_prima_istanza.exe" è aperta da più di x minuti, chiudila;
-se l'istanza "nome_seconda_istanza.exe" è aperta da più di x minuti, chiudila;

in questo modo ne viene chiusa solo una perché l'altra è aperta da soli pochi secondi.

se può essere utile io pensavo di usare il comando da console "taskkill" che ha come parametro anche cputime, ma come lo scrivo in c? Avete altre idee?

Una cosa del genere la puoi fare facilmente in Python, utilizzando psutil:
http://code.google.com/p/psutil

Esempio:



>>> import psutil
>>> import time
>>> p1 = psutil.Process(1000) # 1000 == pid del primo processo
>>> p2 = psutil.Process(1001) # 1001 == pid del secondo processo
>>> # il processo è partito 500 secondi fa
>>> time.time() - p1.create_time
500.876
>>> # lo voglio uccidere
>>> p1.kill()



Se volessi farlo in puro C dovresti ottenere l'handler del processo che ti interessa (OpenProcess), determinare quando è stato creato (GetProcessTimes) e ucciderlo (TerminateProcess).
A occhio e croce direi 50 volte più lungo e un altro tot più complesso.

Tarrion
06-06-2010, 16:25
hai ragione! penso che allora mi convertirò a Python, solo che da questo codice mi pare che si supponga noto l'id del processo da terminare, io invece non lo conosco quindi se ci fosse un comando per ottenere il pid dal nome del processo questa sarebbe la soluzione migliore.

billiejoex
06-06-2010, 16:53
Con psutil puoi ricavare tutti gli id dei processi in esecuzione:



>>> psutil.get_pid_list()
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
30, 31, 32, 35, 36, 37, 38, 39, 40, 41, 42, 46, 47, 48,
...
...
...
1653, 1681, 1726, 1855, 1880, 2299, 2858, 2859, 2860,
2861, 2862, 2863, 2864, 2868, 2869, 2870, 2871, 8569,
8935, 8938, 8940, 8967, 8985, 9020, 9021, 9022, 9039,
9136]
>>>


...e per ognuno di essi il nome dell'eseguibile, esempio:



>>> p = psutil.Process(543)
>>> p.name
'svchost.exe'


...per cui con una funzione del genere te la dovresti cavare (non testato):



def pid_from_name(name):
"""Given a process name (e.g. "svchost.exe") return its pid"""
pids = psutil.get_pid_list()
for pid in pids:
p = psutil.Process(pid)
if p.name == name:
return pid
raise ValueError("No process with name '%s' found" % name)


Utilizzo:



>>> pid_from_name("svchost.exe")
524

Tarrion
06-06-2010, 17:39
Magnifico! Ho risolto! Grazie infinite, ecco il mio codice:



import psutil
import time
for pid in psutil.get_pid_list():
p = psutil.Process(pid)
if p.name == 'notepad.exe':
if time.time() - p.create_time >= 500:
p.kill()

billiejoex
06-06-2010, 17:59
Usa questo:



import psutil
import time

for p in psutil.process_iter():
if p.name == 'notepad.exe':
if time.time() - p.create_time >= 500:
p.kill()


Dovrebbe evitare in automatico che ti si schianti tutto nel caso in cui cerchi di leggere informazioni di un processo di sistema che non sei autorizzato a interrogare (es: alcuni lanciati con l'utente NT AUTHORITY SYSTEM).

Loading