[C#] Identificar cuando una aplicación externa es cerrada.

Iniciado por HappyNewYear, 30 Abril 2010, 20:12 PM

0 Miembros y 1 Visitante están viendo este tema.

HappyNewYear

El título lo dice todo, ¿es posible? Si lo es, ¿podrían darme un ejemplo?

MANULOMM

pues se que es posible saber los procesos que hay en memoria, lo que podrias hacer es mirar cada determinado tiempo que procesos hay en memoria y asi controlar cuales se abren y cuales se cierran.

Atentamente,

Juan Manuel Lombana
Microsoft Student Partner
Microsoft Certified Professional
Medellín - Colombia


Keyen Night

#2
Hace tiempo hice esta clase para capturar los procesos abiertos, capturar los cerrados es casi la misma idea, pero está en Vb.Net:
Código (vbnet) [Seleccionar]
Public Class ProcessEvent

   Private _Begin As New Process, _
               _CProcess As Integer = Process.GetProcesses.Count

   Private WithEvents lTimer As New Timer With {.Enabled = False, .Interval = 100}

   Public Event BeginProcess(ByVal e As Process)

   Private Function LastProcess() As Process
       Dim Far As Integer = 0, _
       VeryFar As Integer = 1
       LastProcess = New Process

       For Each lProcess As Process In Process.GetProcesses
           Try
               Far = DateDiff(DateInterval.Second, lProcess.StartTime, Now)
               If VeryFar > Far Then
                   VeryFar = Far
                   LastProcess = lProcess
               End If
           Catch
               Continue For
           End Try
       Next

   End Function

   Public Property Enabled() As Boolean
       Get
           Return lTimer.Enabled
       End Get
       Set(ByVal value As Boolean)
           lTimer.Enabled = value
       End Set
   End Property

   Private Sub lTimer_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles lTimer.Tick
       On Error Resume Next

       If (Process.GetProcesses.Count - _CProcess) > 0 Then
           RaiseEvent BeginProcess(LastProcess)
       End If

       _CProcess = Process.GetProcesses.Count

   End Sub
End Class

La Fé Mueve Montañas...
                                    ...De Dinero

La programación es más que un trabajo es más que un hobby es una pasión...

Atrum

#3
Una de las opciones es utilizar un timer para verificar el proceso cada determinado tiempo, yo personalmente lo haria haciendo uso del Process y generar un evento para cuando el programa termine,  todo esto dentro de un threadPool para verificar multiples procesos si es necesario, en este codigo solo utilizo la primera coincidencia de la matriz GetProcessByName, pero si haces un foreach y con el treadPool puedes verificar todos los procesos del mismo nombre y aplicar el "Monitor" a cada uno de ellos.

Espero te funcione correctamente (yo lo corri sin problemas ;-) ).

Solo tengo un form un textbox y un button, hay que agregar las referencias System.Threading y System.Diagnostics.

Código (csharp) [Seleccionar]

using System;
using System.ComponentModel;
using System.Windows.Forms;
using System.Threading;
using System.Diagnostics;

namespace WindowsFormsApplication1
{
    //Declaramos el delegado para nuestro evento
    public delegate void ProccesClosed(string ProcName);

    public partial class Form1 : Form
    {
        //Declaro una variable global para el nombre del proceso
        public string ProcName;

        //Declaro mi evento nuevo, verifica que el IDE te asocie el
        //evento con el delegado (Aparece coloreado en azul claro)
        //lo digo por que no se que hice mal que a mi no me lo asocio a la primera
        public  event ProccesClosed  ProcClosed;

        public Form1()
        {
            InitializeComponent();
            //Agregamos el handler del evento
            this.ProcClosed += new ProccesClosed(ProcesoTerminado);
        }

        //Aqui la funcion que cargaremos en el hilo(thread) para verificar
        //Que el proceso termine, todos los parametros deben ser del tipo Object
        public void VerificarProceso(object  NombreProceso)
        {
            //Declaro la matriz de procesos y la lleno con los procesos que
            //tengan el nombre casteando mi objeto como string
            Process[] Proc;
            Proc = Process.GetProcessesByName((string)NombreProceso);
            //Verificamos que exista al menos una coincidencia, si no
            //obtendriamos exepcion de referencia nula
            if (Proc.Length != 0)
            {
                //Solo verifico la primera coincidencia
                Proc[0].WaitForExit();
                //Verificamos que el evento contenga el handler
                if (ProcClosed != null)
                    //se desencadena el evento
                    ProcClosed((string)NombreProceso);
            }
            else
                //En caso de que no exista dicho proceso
                MessageBox.Show("No existe el proceso " + (string)NombreProceso);
                       
        }

        //Esta es la funcion que llama el evento ProcClosed
        public void ProcesoTerminado(string NombreProcesso)
        {
            MessageBox.Show("Se ha terminado el proceso " + NombreProcesso);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            ProcName = textBox1.Text;
            //Agregamos La funcion al ThreadPool, podemos agregar cuantas
            //queramos monitoreando procesos distintos
            ThreadPool.QueueUserWorkItem(VerificarProceso, ProcName );
        }
       
    }
}


Solo bastaria ejecutar y colocar en el textbox el nombre de un proceso sin la extension, como por ejemplo "notepad" o "calc", y cada thread desencadenara el evento cuando termine el proceso.

Cualquier error haganmelo saber

Suerte