Visual Basic 2008 :: Obtener el identificador de sesión de un proceso en ejecución

Ayer estuve presente en la presentación que se hizo en MAD.NUG sobre la gestión de código con Visual Studio Team System y la verdad es que la sesión me gustó mucho.
Tuvimos problemas para grabar la sesión (esperamos que la próxima vez no nos ocurra lo mismo) y la asistencia fue nutrida, aunque en honor a la verdad, esperaba que hubiera más gente.
Lo mejor de este tipo de charlas y sesiones es que en ellas se puede no solo aprender cosas de la presentación en cuestión, sino que los comentarios y preguntas que se hacen pueden ayudar a todos en algún momento dado.
De hecho, el motivo de esta entrada llega gracias al comentario de una de esas personas que en mi caso, me hizo cuando acabamos la sesión.
¿Cómo obtener el identificador de la sesión de un determinado proceso en ejecución?.
En un primer momento pensé en WMI, pero luego en mi cabeza y dándole vueltas mientras iba a casa me acordé que había otra forma, gracias al nombre de espacio System.Diagnostics.
Así que me puse a pensar como obtener el identificador de la sesión y otros valores, y este es el resultado que he obtenido:

¿Cómo llegar a esto?.
En el formulario principal he añadido dos controles Button, un control ComboBox, y contenedores y separadores a parte, 5 controles Label donde volcar la información que obtiene la aplicación.
El código está comentado, así que tampoco hace falta que comente más, lo único, que creé además del formulario principal, una estructura.
Aquí va el código:
Estructura (ProcessStructure.vb):
''' <summary> ''' Estructura que contendrá algunos de los elementos de un proceso ejecutado en memoria. ''' </summary> ''' <remarks></remarks> Public Structure ProcessStructure ''' <summary> ''' Nombre del proceso ''' </summary> ''' <remarks></remarks> Public Name As String ''' <summary> ''' Programa o aplicación del proceso ''' </summary> ''' <remarks></remarks> Public ModuleName As String ''' <summary> ''' PID del proceso o process identifier, que es el número utilizado ''' por el sistema operativo para identificar a un proceso de forma única. ''' Este identificador se puede utilizar para eliminar un proceso en ejecución. ''' </summary> ''' <remarks></remarks> Public PID As Integer ''' <summary> ''' No soportado en Windows 98, indica la sesión en la que está ejecutándose una aplicación. ''' </summary> ''' <remarks></remarks> Public SessionID As Integer ''' <summary> ''' Función ToString() que devuelve uno de los elementos de la estructura. ''' </summary> ''' <returns></returns> ''' <remarks></remarks> Public Overrides Function ToString() As String Return Name End Function End Structure ' ProcessStructure |
Código del formulario (MainForm.vb):
''' <summary> ''' Clase del formulario principal de la aplicación. ''' </summary> ''' <remarks></remarks> Public Class MainForm ''' <summary> ''' Evento que se lanza al cargar el formulario. ''' </summary> ''' <param name="sender"></param> ''' <param name="e"></param> ''' <remarks></remarks> Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load ' Limpiamos los controles de información de los procesos ClearProcessesControls(True) End Sub ''' <summary> ''' Evento que se ejecuta para obtener todos los procesos del sistema. ''' </summary> ''' <param name="sender"></param> ''' <param name="e"></param> ''' <remarks></remarks> Private Sub btnGetProcesses_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnGetProcesses.Click ' Limpiamos los controles de información de los procesos ClearProcessesControls(False) ' Obtenemos la lista de procesos GetProcessesList() End Sub ''' <summary> ''' Método privado que se encarga de limpiar todos los controles y dejarlos vacíos. ''' </summary> ''' <param name="flag">Si el valor pasado como parámetro es True, limpia todos los controles de la ventana. ''' Si es False, limpia solo los controles relacionados con la obtención de todos los procesos del sistema.</param> ''' <remarks></remarks> Private Sub ClearProcessesControls(ByVal flag As Boolean) ' Limpiamos los controles de información de los procesos Me.cboProcesses.Items.Clear() Me.lblProcessName.Text = "" Me.lblProcessModuleName.Text = "" Me.lblProcessPID.Text = "" Me.lblProcessSessionID.Text = "" If flag Then ' Limpiamos todos los controles del proceso en ejecución Me.lblMyProcess.Text = "" Me.lblMyProcessName.Text = "" Me.lblMyProcessModuleName.Text = "" Me.lblMyProcessPID.Text = "" Me.lblMyProcessSessionID.Text = "" End If End Sub ''' <summary> ''' Método privado que se encarga de obtener la lista de procesos del sistema en ejecución. ''' </summary> ''' <remarks></remarks> Private Sub GetProcessesList() ' Obtenemos la lista de procesos Dim processList As System.Diagnostics.Process() processList = System.Diagnostics.Process.GetProcesses() ' Obtenemos la información por cada proceso en la lista de procesos For Each process As System.Diagnostics.Process In processList ' Instanciamos una estructura de proceso Dim processDetailStructure As New ProcessStructure() ' Indicamos el nombre del proceso processDetailStructure.Name = process.ProcessName ' Si el nombre del proceso es "SYSTEM" o "IDLE", entonces ' no podemos obtener el ModuleName, ya que es un proceso de sistema If processDetailStructure.Name.ToUpper() = "SYSTEM" Or _ processDetailStructure.Name.ToUpper() = "IDLE" Then processDetailStructure.ModuleName = "System Process" Else processDetailStructure.ModuleName = process.MainModule.ModuleName End If ' Obtenemos el PID o process identifier del proceso processDetailStructure.PID = process.Id ' Obtenemos el id de sesión en la cuál se está ejecutando nuestro proceso processDetailStructure.SessionID = process.SessionId ' Mostramos la estructura del proceso en el control ComboBox Me.cboProcesses.Items.Add(processDetailStructure) Next ' Seleccionamos el primer elemento si hay elementos seleccionables If Me.cboProcesses.Items.Count > 0 Then Me.cboProcesses.SelectedIndex = 0 End If End Sub ''' <summary> ''' Evento que se lanza cuando se selecciona un elemento del control ComboBox, ''' mostrando en pantalla la información contenida en el elemento seleccionado. ''' </summary> ''' <param name="sender"></param> ''' <param name="e"></param> ''' <remarks></remarks> Private Sub cboProcesses_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) & _ Handles cboProcesses.SelectedIndexChanged ' Obtenemos la información del elemento seleccionado Dim processDetailStructure As ProcessStructure = Me.cboProcesses.SelectedItem() ' Mostramos los detalles Me.lblProcessName.Text = processDetailStructure.Name Me.lblProcessModuleName.Text = processDetailStructure.ModuleName Me.lblProcessPID.Text = processDetailStructure.PID Me.lblProcessSessionID.Text = processDetailStructure.SessionID End Sub ''' <summary> ''' Evento que se ejecuta para obtener los detalles del proceso en ejecución. ''' Muestra los detalles de la propia aplicación que se está ejecutando. ''' </summary> ''' <param name="sender"></param> ''' <param name="e"></param> ''' <remarks></remarks> Private Sub btnMyProcess_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnMyProcess.Click ' Obtenemos información del proceso en cuestión Dim process As System.Diagnostics.Process = System.Diagnostics.Process.GetCurrentProcess Me.lblMyProcess.Text = System.Environment.CurrentDirectory.ToString() Me.lblMyProcess.Text = Application.ExecutablePath.ToString() Me.lblMyProcessName.Text = process.ProcessName Me.lblMyProcessModuleName.Text = process.MainModule.ModuleName Me.lblMyProcessPID.Text = process.Id Me.lblMyProcessSessionID.Text = process.SessionId End Sub End Class ' MainForm |
Finalmente, si lo que quieres es descargarte el código completo de la aplicación, lo podrás hacer
desde el siguiente enlace (17 Kb).
Cross Posted from Jorge Serrano - MVP Visual Developer - VB