title: How to close WPF system tray application from another app?
body: <p>I have a <strong>windowless</strong> WPF application using great <a href="http://www.hardcodet.net/wpf-notifyicon" rel="nofollow noreferrer">NotifyIcon</a> by Philipp Sumi. I'm gladly replacing my old WinForms based version, however, I have one problem.</p>
  
  <p>My app has uninstaller that closes the tray application before removing the executable files. The closing thing is done with sending WM_CLOSE message to the tray application process. It's relatively easy to listen to such messages with WinForms, however - how to do it with WPF, and then again, maybe there is a better way of remotely telling my WPF tray application to shutdown? I mean, what else is there? Pipes?</p>
  
  <p>THIS IS NOT A DUPLICATE.
  There is no "main window" in my app. So nothing referring to main windows will work.</p>
  
  <p>I believe the system has to have a way to tell an app to close itself, in case of let's say restart or shutdown. That's why we get "this and that app is not responding, do you want to shutdown anyway" or similar messages.</p>
  
  <p>Here's my naive approach:</p>
  
  <pre><code>using (var process = Process.GetProcessesByName("MyApp").FirstOrDefault()) {
      const uint WM_SYSCOMMAND = 0x0112;
      const uint SC_CLOSE = 0xF060;
      const uint WM_CLOSE = 0x0010;
      var hwnd = process.MainWindowHandle;
      NativeMethods.SendMessage(hwnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
      foreach (ProcessThread thread in process.Threads) {
          NativeMethods.PostThreadMessage(
              (uint)thread.Id,
              WM_SYSCOMMAND, 
              (IntPtr)SC_CLOSE,
              IntPtr.Zero
          );
      }
  } 
  </code></pre>
  
  <p>Doesn't work. Of course hwnd is always IntPtr.Zero, unless I create a window, obviously I don't want to create window. The application threads ignore SC_CLOSE, so no joy here either.</p>
  
  <p>OK, I tried to create invisible window. That approach works if the window has the ShowInTaskBar set to true. Not good.</p>
  
  <p>Then I created a sponge window, from System.Windows.Forms.NativeWindow.</p>
  
  <p>Of course that invisible window is perfectly capable of receiving WM_CLOSE and any other messages, however, it is not set as the process main window, so I cannot target it with my uninstall app.</p>
  
  <p>Currently I'm out of ideas.</p>