Gestione dei Processi
Un sistema operativo svolge, in continuazione e parallelamente, diverse
attivita'. Queste attivita' sono dette Processi. La classe
Process del .Net Framework si occupa della creazione e
controllo di processi. Permette di eseguire tutte quelle operazioni tipiche del
TaskManager di Windows.
Ogni processo che vogliamo controllare viene gestito tramite un'istanza della
classe Process. Inoltre, alcuni metodi statici della stessa
classe ci interfacciano a Processi gia' in esecuzione, fornendoci
appunto un oggetto Process che funziona da wrapper.
Questi metodi statici sono:
-
GetProcesses - Restituisce un array di oggetti Process
corrispondenti ai processi in esecuzione sul sistema
-
GetProcessById - Restituisce un oggetto Process
che si riferisce al processo di cui abbiamo specificato l'identificatore (*)
-
GetProcessByName - Restituisce un array di oggetti Process
che si riferisce a tutti i processi che hanno il nome che abbiamo specificato
(*) Un processo e' identificato, nel sistema operativo, in maniera univoca da un identificatore
di processo, detto Id. Un processo puo' anche essere identificato da
un Handle, come avviene per la maggior parte delle risorse di Windows. Tenete
presente pero' che gli Handles non sono univoci.
La classe Process ci permette di ottenere informazioni sui
diversi processi che stanno girando sul sistema. Queste informazioni riguardano
i Thread e Moduli come le DLL, che ciascun processo puo'
creare e caricare. Le informazioni riguardano anche l'uso di memoria a carico
del processo. Ecco una lista di propieta' utili:
-
EnableRaisingEvents - Permette all'oggetto di notificare, con
un evento, il termine dell'esecuzione del processo che sta gestendo.
-
ExitCode - Restituisce il codice di uscita del thread, al
termine dell'esecuzione.
-
ExitTime - Restituisce il tempo in cui il processo e'
terminato.
-
HasExited - Dice se il processo e' attivo o e' terminato.
-
Id - Restituisce l'Id che il sistema ha assegnato al processo.
-
Modules - Raccoglie in un array tutti moduli caricati dal
processo.
-
ProcessName - Indica il nome del processo.
-
Responding - Ci informa se il processo risponde oppure e'
bloccato.
-
StartInfo - Imposta o restituisce un'oggetto di tipo StartInfo
che raccoglie informazioni sull'avvio di un nuovo processo che si vuole creare.
-
StartTime - E' il tempo di avvio del processo.
-
Threads - Raccoglie in un array tutti thread creati dal
processo.
Vediamo come raccogliere delle informazioni sui processi che girano sul
sistema. Creiamo un'applicazione Form che contenga i seguenti
controlli:
Controllo |
Text |
Name |
Button |
Get Processes |
btnGetProcesses |
Button |
Info |
btnInfo |
Label |
"" |
lblResponding |
Label |
"" |
lblThreads |
ListBox |
-- |
lstProc |
LisBox |
-- |
lstModules |
Con l'esempio proposto vogliamo creare un'appplicazione che 1) listi tutti i
processi nel sistema con relativi Id, 2) permetta di selezionarne uno e mostri
2.1) se risponde o meno, 2.2) il numero di thread creati 2.3) tutti i moduli
caricati.
Imports System.Diagnostics.Process
Imports System.Text.RegularExpressions.Regex
1) Il click sul pulsante "Get Processes" lancia il seguente evento.
Quest'ultimo, tramite il metodo statico GetProcesses raccoglie
in un array p() tutti i processi attivi. Quindi li inserisce in una ListBox
affiancando a ciascuno di loro il relativo Id che ci servira', in seguito, per
reperire ulteriori informazioni sul processo.
Private Sub btnGetProcesses_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnGetProcesses.Click
Me.Cursor = Cursors.WaitCursor
Dim p() As Process = Process.GetProcesses
lstProc.Items.Clear()
Dim i As Integer
For i = 0 To p.Length - 1
lstProc.Items.Add(p(i).Id & " - " & p(i).ProcessName)
Next
Me.Cursor = Cursors.Default
End Sub
2) Dopo aver selezionato un processo nella ListBox dei processi, e' possibile
cliccare sul pulsante "Info", per ottenere ulteriori informazioni. Ho suddiviso
il corpo della procedura in vari blocchi. Il primo si occupa di reperire
l'identificatore di processo, nella riga selezionata. Il secondo, tramite GetProcessById
ottiene un oggetto Process che continene le informazioni sul
processo desiderato. Il terzo blocco reperisce le informazioni in base alle
proprieta' che abbiamo gia' elencato e le visualizza.
Private Sub btnInfo_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnInfo.Click
If lstProc.SelectedIndex = -1 Then Exit Sub
'
Dim procline As String = lstProc.SelectedItem
Dim rExp As New System.Text.RegularExpressions.Regex(" - ")
Dim s() As String = rExp.Split(procline)
'
Dim pInfo As Process = Process.GetProcessById(CInt(s(0)))
'
lblResponding.Text = IIf(pInfo.Responding, "", "Not ") & "Responding"
lblThreads.Text = pInfo.Threads.Count & " threads"
lstModules.Items.Clear()
Dim en As IEnumerator = pInfo.Modules.GetEnumerator()
Do While en.MoveNext()
lstModules.Items.Add(en.Current)
Loop
pInfo.Close()
End Sub
Eseguire applicazioni
L'altro utilizzo della classe Process e' quello di avviare
nuovi processi. Possiamo ad esempio lanciare applicazioni come il notepad.exe
od altro. Facciamo questo con il metodo Start, avvalendoci
anche di un oggetto ausiliario chiamato ProcessStartInto che
ne setta le informazioni di avvio, quali il percorso dell'applicazione, i
parametri etc. L'oggetto Process ci permette anche di forzare
la terminazione del processo con il metodo Kill
1) Con il prossimo esempio, lanceremo l'Internet Explorer alla sola presione di
un pulsante. Con la variabile MyProc avvolgeremo il processo relativo
all'explorer, in StartTime memorizzeremo il tempo d'inizio del
processo. Quando il processo termina (chiudete l'explorer) un evento
notifichera' la nostra applicazione e noi potremo mostrare delle informazioni
del tipo: tempo d'inizio, tempo di fine, durata e codice di uscita.
Imports System.Diagnostics.Process
Dim MyProc As Process
Dim StartTime As DateTime
2) Usiamo il metodo Start statico per lanciare l'explorer.
Esso ci restituira' un oggetto Process con il quale gestiremo
il processo creato. E' importante memorizzare la proprieta' StartTime ora,
poiche' una volta terminato il processo, questa non sara' piu' disponibile.
Quindi ci occupiamo di abilitare l'evento di terminazione ed agganciarlo alla
nostra procedura handler proc_Exited.
Private Sub btnExecute_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnExecute.Click
Dim si As New ProcessStartInfo("iexplore.exe")
MyProc = Process.Start(si)
StartTime = MyProc.StartTime
AddHandler MyProc.Exited, AddressOf proc_Exited
MyProc.EnableRaisingEvents = True
End Sub
3) Quando il processo termina, l'oggetto a cui si riferisce MyProc
genera il seguente evento. E noi recuperiamo delle informazioni inerenti ai
tempi del processo e le mostriamo in una MessageBox.
Private Sub proc_Exited(ByVal sender As Object, _
ByVal e As System.EventArgs)
Dim msg As String
msg = "Process Exited, code " & MyProc.ExitCode & vbCrLf
msg = msg & "Started at " & StartTime & vbCrLf
msg = msg & "Stopped at " & MyProc.ExitTime & vbCrLf
msg = msg & "Duration " & MyProc.ExitTime.Subtract( _
MyProc.StartTime).ToString
MessageBox.Show(msg)
End Sub
Ultimo aggiornamento 13/01/2004
|