adszone.org
venerdì 20 settembre 2024
"Il modo corretto di pensare il software"
home
consulenza  vb.net  contatti 
  Visual Basic .NET
  I Processi
Domande

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