title: Monitor Outlook startup/closure
body: <p>You will find hereafter an extract of a class aiming at adding a button in Outlook context menu if Outlook is launched.
  When outlook is not launched, a Start EventWatcher is armed to detect Outlook startup.
  A Close EventWatcher is also armed to allow ressources clean-up when Outlook is closed.</p>
  
  <p>I run this code in Admin mode but the application randomly crashes. If I disable all the code around EventWatchers it's stable. I can't find the origin of these crashes, can you help me ? (Forgive me for the french comments in the text).</p>
  
  <p>The entry point is the tryHook method.</p>
  
  <pre><code>public class OutlookIF
  {
      // Attributs métiers       
      private Outlook.Application outlook = null;
  
      // Process watch
      private ManagementEventWatcher startWatch =
          new ManagementEventWatcher(new WqlEventQuery("SELECT * FROM Win32_ProcessStartTrace WHERE ProcessName = 'OUTLOOK.EXE'"));
      private ManagementEventWatcher stopWatch =
          new ManagementEventWatcher(new WqlEventQuery("SELECT * FROM Win32_ProcessStopTrace WHERE ProcessName = 'OUTLOOK.EXE'"));      
  
      // Gestion du singleton
      private static OutlookIF v_instance = null;
      public static OutlookIF Instance
      {
          get
          {
              if (v_instance == null)
                  v_instance = new OutlookIF();
  
              return v_instance;
          }
      }
  
      private OutlookIF()
      {
          // Récupération des évènements EventArrived
          startWatch.EventArrived += new EventArrivedEventHandler(startWatch_EventArrived);
          stopWatch.EventArrived += new EventArrivedEventHandler(stopWatch_EventArrived);         
      }
  
      // Vérification de la présence d'un process Outlook running
      private bool outlookIsLaunched = (Process.GetProcessesByName("outlook").Count() &gt; 0);
  
      //Tentative de connexion à Outlook
      public void tryHook()
      {
          if (this.outlookIsLaunched)
          {
              this.hookOutlook();
              this.stopWatch.Start();
          }
          else
              this.startWatch.Start();     
      }
  
      // Ajout du menu contextuel à Outlook
      private void hookOutlook()
      {
          // Création de l'objet application
          if (this.outlookIsLaunched)
              this.outlook = Marshal.GetActiveObject("Outlook.Application") as Outlook.Application;
          else
              this.outlook = new Outlook.ApplicationClass();
  
          // Création de l'entrée dans le menu contextuel           
          this.outlook.ItemContextMenuDisplay += new Outlook.ApplicationEvents_11_ItemContextMenuDisplayEventHandler(addEntrytoContextMenu);          
      }
  
      // Nettoyage des objets
      private void clean()
      {
          Marshal.FinalReleaseComObject(this.outlook); 
          this.outlook = null;
      }
  
      private void startWatch_EventArrived(object sender, EventArrivedEventArgs e)
      {
          // Arrêt de l'écoute de l'ouverture
          this.startWatch.Stop();
  
          TrayIcon.afficheMessage("ProcessWatch", "Ouverture d'Outlook");           
          this.hookOutlook();
  
          // Démarrage de l'écoute de la fermeture
          this.stopWatch.Start();
      }
  
      private void stopWatch_EventArrived(object sender, EventArrivedEventArgs e)
      {
          // Arrêt de l'écoute de la fermeture
          this.stopWatch.Stop();
  
          TrayIcon.afficheMessage("ProcessWatch", "Fermeture d'Outlook");           
          this.clean();
  
          // Démarrage de l'écoute de l'ouverture
          this.startWatch.Start();
      }
  }
  </code></pre>