Search code examples
c#.netappbar

Clean up AppBar after process kill


I have written an Application Desktop Toolbar (a.k.a AppBar), it works great except for the fact that if I kill the process, the AppBar code never gets a chance to cleanup by sending an ABM_REMOVE. The problem is that this basically screws the users desktop up. The AppBar is written in .NET using interop code.

Does anyone know of a way to clean this resource up, even in the case of a process kill from TaskManager?


Solution

  • When a process is killed from Task Manager, no events are raised within that application. It's common to use a seperate helper application that listens for the Win32_ProcessStopTrace event for your process. You can use the WqlEventQuery, which is part of System.Management for this.

    Here is some example code for this from a MegaSolutions post.

    using System;
    using System.Collections.Generic; 
    using System.Text; 
    using System.Management; 
    
    
    class ProcessObserver : IDisposable 
    { 
        ManagementEventWatcher m_processStartEvent = null; 
        ManagementEventWatcher m_processStopEvent = null; 
    
    
        public ProcessObserver(string processName, EventArrivedEventHandler onStart, EventArrivedEventHandler onStop) 
        { 
            WqlEventQuery startQuery = new WqlEventQuery("Win32_ProcessStartTrace", String.Format("ProcessName='{0}'", processName)); 
            m_processStartEvent = new ManagementEventWatcher(startQuery); 
    
    
            WqlEventQuery stopQuery = new WqlEventQuery("Win32_ProcessStopTrace", String.Format("ProcessName='{0}'", processName)); 
            m_processStopEvent = new ManagementEventWatcher(stopQuery); 
    
    
            if (onStart != null) 
                m_processStartEvent.EventArrived += onStart; 
    
    
            if (onStop != null) 
                m_processStopEvent.EventArrived += onStop; 
        } 
    
    
        public void Start() 
        { 
            m_processStartEvent.Start(); 
            m_processStopEvent.Start(); 
        } 
    
    
        public void Dispose() 
        { 
            m_processStartEvent.Dispose(); 
            m_processStopEvent.Dispose(); 
        } 
    }