1

我想知道如果无法为新实例创建互斥锁,是否有人可以告诉我将我的应用程序带到前台的最佳方法是什么。

例如:应用程序 X 正在运行但在后台。我看不到它,所以我尝试运行另一个实例;因为互斥体返回 false,所以最好的办法是将现有实例带到前台。

任何人都知道与您自己的应用程序交互但来自单独进程的最佳方式?

4

4 回答 4

2

您将需要获得一个 hWnd 到另一个应用程序的主窗口。我记得如何做到这一点的唯一方法是遍历所有窗口,直到找到你的。可能有更直接的方法

[DllImport("user32.dll")] private static extern 
              int EnumWindows(EnumWindowsProc ewp, int lParam); 

public delegate bool EnumWindowsProc(int hWnd, int lParam);

public void EnumerateAllWindows()
{
   EnumWindowsProc ewp = new EnumWindowsProc(EvalWindow);
   EnumWindows(ewp, 0);
 }

private bool EvalWindow(int hWnd, int lParam)
{
    //this will be called for each window..         
    // use GetWindowThreadProcessId to get the PID for each window
    // and use Process.GetProcessById to get the PID you are looking for
    // then bring it to foregroun using of these calls below:

}

    [DllImport("user32.dll")]
    public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

    [DllImport("user32.dll")]
    public static extern bool BringWindowToTop(IntPtr hWnd);

    DllImport("user32.dll")] public static extern bool SetForegroundWindow(IntPtr hWnd
于 2009-11-14T11:25:53.733 回答
2

实现目标的一种方法是创建命名共享内存。

第一个应用程序将创建命名的共享内存并将其存储在其窗口句柄、进程标识符或任何其他对此有用的信息中。

当第二个应用程序尝试创建同名的共享内存时,它将检索同一共享内存的句柄,而返回值将告诉您该对象已经存在。然后第二个应用程序可以从共享内存中读取窗口句柄和任何其他信息。然后它可以使用BringWindowToTop(),SetForegroundWindow()或类似的。

您将在 Windows SDK 中找到命名共享内存的示例。虽然此示例使用直接的 Win32 API,但我很确定您可以在 C# 中执行等效的操作。

于 2009-11-14T12:36:09.283 回答
2

.Net 内置了一项功能,通过在第一个实例中引发事件,让您的应用程序的第二个实例与第一个实例进行通信。虽然它是 VB.Net 的一部分,但它也可以与 C# 一起使用。

但是,了解这些错误非常重要。使用某些防火墙,甚至无法打开一个实例——您的应用程序在启动时崩溃!请参阅Bill McCarthy 的这篇优秀文章,了解更多详细信息和替代技术。他使用 .NET 3.5 中的管道从第二个实例返回到第一个实例。我建议你使用它。他的代码是 VB.Net,但您可以使用 Telerik 转换为 C#

于 2009-11-14T14:17:44.703 回答
0

谷歌的 forceForegroundWindow (如果你在 Windows 上),无论如何

于 2010-02-23T17:32:05.420 回答