我有一个应用程序,一次只能打开一个自身的实例。为了实现这一点,我使用以下代码:

        System.Diagnostics.Process[] myProcesses = System.Diagnostics.Process.GetProcesses();
        System.Diagnostics.Process me = System.Diagnostics.Process.GetCurrentProcess();
        foreach (System.Diagnostics.Process p in myProcesses)
        {
            if (p.ProcessName == me.ProcessName)
                if (p.Id != me.Id)
                {
                    //if already running, abort this copy.
                    return;
                }
        }
        //launch the application.
        //...

它工作正常。我还希望它能够集中处理已经运行的副本的形式。也就是说,在返回之前,我想将此应用程序的另一个实例置于前台。

我怎么做?

回复:SetForeGroundWindow:

SetForeGroundWindow可以正常工作:
    [System.Runtime.InteropServices.DllImport("user32.dll")]
    public static extern bool SetForegroundWindow(IntPtr hWnd);

    //...
                if (p.Id != me.Id)
                {
                    //if already running, focus it, and then abort this copy.
                    SetForegroundWindow(p.MainWindowHandle);
                    return;
                }
    //...

如果没有最小化窗口,这的确会将窗口带到前景。惊人的。
但是,如果将窗口最小化,则它将保持最小化。

它需要最小化。

通过SwitchToThisWindow解决方案(有效!):
    [System.Runtime.InteropServices.DllImport("user32.dll")]
    public static extern void SwitchToThisWindow(IntPtr hWnd, bool fAltTab);

    [STAThread]
    static void Main()
    {
        System.Diagnostics.Process me = System.Diagnostics.Process.GetCurrentProcess();
        System.Diagnostics.Process[] myProcesses = System.Diagnostics.Process.GetProcessesByName(me.ProcessName);
        foreach (System.Diagnostics.Process p in myProcesses)
        {
            if (p.Id != me.Id)
            {
                SwitchToThisWindow(p.MainWindowHandle, true);
                return;
            }
        }
        //now go ahead and start our application ;-)

最佳答案

我遇到了同样的问题,SwitchToThisWindow()对我来说效果最好。唯一的限制是您必须安装XP sp1。我玩了SetForegroundWindow,ShowWindow,它们在将窗口拉入 View 时都遇到了问题。

07-27 15:07