如何从Win32句柄获取System.Windows.Form实例?

Ian*_*emp 5 c# winapi interop ipc winforms

以下代码实现了一个简单的单例,确保只能运行我的应用程序的一个实例.但是,如果启动了另一个实例,我需要能够获取该实例的命令行参数,将它们传递给初始实例,然后终止第二个实例.

当我试图抓住应用程序的第一个实例时,问题出现了.一旦我找到了该实例的主窗体的句柄,我将它传递给Control.FromHandle()方法,期望得到一个MainForm.相反,返回值始终是null.(Control.FromChildHandle()给出相同的结果.)

因此,我的问题很简单:我做错了什么?这在.NET中甚至可能吗?

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;
  }
}
Run Code Online (Sandbox Code Playgroud)

Han*_*ant 4

.NET 框架很好地支持单实例应用程序。检查此线程以获取完全满足您需要的示例。