title: How do I get a System.Windows.Form instance from its Win32 handle?
body: <p>The following code implements a simple singleton that ensures only 1 instance of my application can be run. However, if another instance is started, I need to be able to grab that instance's command-line arguments, pass them to the initial instance, then terminate the second instance.</p>
  
  <p>The issue comes in when I'm attempting to get hold of the first instance of the application. Once I've found the handle of that instance's main form, I pass it to the <code>Control.FromHandle()</code> method, expecting to get back a <code>MainForm</code>. Instead, the return value is always <code>null</code>. (<code>Control.FromChildHandle()</code> gives the same result.)</p>
  
  <p>Therefore, my question is simply: what am I doing wrong? And is this even possible in .NET?</p>
  
  <pre><code>public class MainForm : Form
  {
  [DllImport("user32")]
  extern static int ShowWindowAsync(IntPtr hWnd, int nCmdShow);
  
  [DllImport("user32")]
  extern static bool SetForegroundWindow(IntPtr hWnd);
  
  private Mutex singletonMutex;
  
  private void MainForm_Load(object sender, EventArgs e)
  {
    bool wasCreated;
    singletonMutex = new Mutex(false, Application.ProductName + "Mutex", out wasCreated);
  
    // returns false for every instance except the first
    if (!wasCreated)
    {
      Process thisProcess = Process.GetCurrentProcess();
      Process[] peerProcesses = Process.GetProcessesByName(thisProcess.ProcessName.Replace(".vshost", string.Empty));
  
      foreach (Process currentProcess in peerProcesses)
      {
        if (currentProcess.Handle != thisProcess.Handle)
        {
          ShowWindowAsync(currentProcess.MainWindowHandle, 1); // SW_NORMAL
          SetForegroundWindow(currentProcess.MainWindowHandle);
  
          // always returns null !!!
          MainForm runningForm = (MainForm) Control.FromHandle(currentProcess.MainWindowHandle);
  
          if (runningForm != null)
          {
            runningForm.Arguments = this.Arguments;
            runningForm.ProcessArguments();
          }
  
          break;
        }
      }
  
      Application.Exit();
  
      return;
    }
  }
  </code></pre>