代码之家  ›  专栏  ›  技术社区  ›  Ian Kemp

我如何获得一个系统。窗户。从Win32句柄创建窗体实例?

  •  8
  • Ian Kemp  · 技术社区  · 17 年前

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

    当我试图获取应用程序的第一个实例时,问题就出现了。一旦我找到了该实例主窗体的句柄,我就将其传递给 Control.FromHandle() MainForm null . ( Control.FromChildHandle()

    因此,我的问题很简单:我做错了什么?这在中是否可行。网?

    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;
      }
    }
    
    6 回复  |  直到 17 年前
        1
  •  4
  •   Hans Passant    17 年前

    单实例应用程序得到了很好的支持。NET框架。检查 this thread

        2
  •  3
  •   Henk Holterman    17 年前

    var form = (Form)(Control.FromHandle(myHandle));
    

    编辑

        3
  •  2
  •   Grzenio    17 年前

    您已经有了WindowHandle,但它的使用仅限于Win32 API。WinForms中的任何内容都无法运行。

    选项

    1. 使用一些低级的东西 临时文件。

    2. 使用远程处理(WCF)

        4
  •  2
  •   JaredPar    17 年前

    您实际上是在尝试实现一个单例应用程序。互联网上有一些例子(对不起,我自己还没有真正尝试过),例如。

    http://www.codeproject.com/KB/cs/SingletonApplication.aspx

    http://www.nathanm.com/csharp-wpf-singleton-application/

        5
  •  0
  •   Nir    17 年前

    你不能直接调用另一个进程中的代码,你需要使用某种形式的进程间通信

        6
  •  0
  •   Jesse Smith    17 年前

    我使用微软。nobugz指向的线程中描述的VisualBasic.dll库。是的,您可以在C#中使用它。您只需覆盖OnStartupNextInstance,并以最适合您的方式将命令行传递到程序中。

    这比手动摆弄线程要容易得多。