title: Send message to a Windows process (not its main window)
body: <p>I have an application that on a subsequent start detects if there's a process with the same name already running and, if so, activates the running app's window and then exits.</p>
  
  <p>The problem is that the main window could be hidden (only a notification area icon visible), thus leaving me with no window handle.</p>
  
  <p>At startup, previous instance's <code>MainWindowHandle</code> property is 0, so I can't send <code>ShowWindow</code> or <code>PostMessage</code>.</p>
  
  <p>Is there any way I can send a message that can be intercepted by the running app, thus allowing it to display its main window?</p>
  
  <p>The application is written in C#, the code I'm using to achieve this below.</p>
  
  <pre><code>[STAThread]
  static void Main()
  {
      bool createdNew = true;
      using (Mutex mutex = new Mutex(true, "MyMutexName", out createdNew))
      {
          if (createdNew)
          {
              Application.EnableVisualStyles();
              Application.SetCompatibleTextRenderingDefault(false);
              Application.Run(new MainForm());
          }
          else
          {
              Process current = Process.GetCurrentProcess();
              foreach (Process process in Process.GetProcessesByName(current.ProcessName))
              {
                  if (process.Id != current.Id)
                  {
                      Interop.WINDOWINFO pwi = new Interop.WINDOWINFO();
                      IntPtr handle = process.MainWindowHandle;
                      var isVisible = Interop.GetWindowInfo(handle, ref pwi);
                      if (!isVisible)
                      {
                          MessageBox.Show(Constants.APP_NAME + " is already running, check the notification area (near the clock).", 
                                          Constants.APP_NAME, MessageBoxButtons.OK, MessageBoxIcon.Information);//temporary message, until I find the solution
                          //Interop.ShowWindow(handle, Interop.WindowShowStyle.ShowNormal);
                          //Interop.PostMessage(handle, Interop.WM_CUSTOM_ACTIVATEAPP, IntPtr.Zero, IntPtr.Zero);
                      }
                      else
                          Interop.SetForegroundWindow(handle);//this works when the window is visible
                          break;
                      }
                  }
              }
          }
      }
  }
  </code></pre>