如何从其Win32句柄获取System.Windows.Form实例? [英] How do I get a System.Windows.Form instance from its Win32 handle?

查看:138
本文介绍了如何从其Win32句柄获取System.Windows.Form实例?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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.

当我尝试获取应用程序的第一个实例时,就会出现问题.找到该实例的主窗体的句柄后,将其传递给Control.FromHandle()方法,期望返回MainForm.而是,返回值始终为null. (Control.FromChildHandle()给出相同的结果.)

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 Control.FromHandle() method, expecting to get back a MainForm. Instead, the return value is always null. (Control.FromChildHandle() gives the same result.)

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

Therefore, my question is simply: what am I doing wrong? And is this even possible in .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;
  }
}

推荐答案

.NET框架很好地支持了单实例应用程序.检查此线程提供一个完全满足您需求的示例.

Single-instance apps are well supported by the .NET framework. Check this thread for an example that does exactly what you need.

这篇关于如何从其Win32句柄获取System.Windows.Form实例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆