1

我正在执行一项任务,以在同一应用程序的第二个实例启动时从系统托盘恢复和最大化窗口。

当第二个实例启动并且无法获取互斥锁时。它调用以下代码来指示第一个实例显示自己:

public static void ShowFirstInstance()

  {
     WinApi.PostMessage(
        (IntPtr)WinApi.HWND_BROADCAST, 
        WM_SHOWFIRSTINSTANCE, 
        IntPtr.Zero, 
        IntPtr.Zero);
  }

该消息使用以下方式注册:

public static readonly int WM_SHOWFIRSTINSTANCE =
         WinApi.RegisterWindowMessage("WM_SHOWFIRSTINSTANCE|{0}", 250);

我在窗口后面的代码中有以下代码来捕获消息并显示窗口:

private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
      {
         if (msg == SingleInstance.WM_SHOWFIRSTINSTANCE)
         {
             WinApi.ShowToFront(hwnd);
         }

         return IntPtr.Zero;
      }

当我测试它时。每当第一个实例隐藏在系统托盘中时,消息就永远不会被捕获。我想念什么吗?

谢谢,

4

1 回答 1

0

以下是我过去的做法:

应用程序.xaml.cs:

private static readonly Mutex Mutex = new Mutex(true, "{" + YourGuidHere + "}");

//return true if other instance is open, allowing for UI cleanup/suspension while shutdown() is completed
private bool EnforceSingleInstance()
{
    //try...catch provides safety for if the other instance is closed during Mutex wait
    try
    {
        if (!Mutex.WaitOne(TimeSpan.Zero, true))
        {
            var currentProcess = Process.GetCurrentProcess();

            var runningProcess =
                Process.GetProcesses().Where(
                    p =>
                    p.Id != currentProcess.Id &&
                    p.ProcessName.Equals(currentProcess.ProcessName, StringComparison.Ordinal)).FirstOrDefault();

            if (runningProcess != null)
            {
                WindowFunctions.RestoreWindow(runningProcess.MainWindowHandle);

                Shutdown();
                return true;
            }
        }

        Mutex.ReleaseMutex();
    }
    catch (AbandonedMutexException ex)
    {
        //do nothing, other instance was closed so we may continue
    }
    return false;
}

窗口功能:

//for enum values, see http://www.pinvoke.net/default.aspx/Enums.WindowsMessages
public enum WM : uint
{
    ...
    SYSCOMMAND = 0x0112,
    ...
}

//for message explanation, see http://msdn.microsoft.com/en-us/library/windows/desktop/ms646360(v=vs.85).aspx
private const int SC_RESTORE = 0xF120;

public static void RestoreWindow(IntPtr hWnd)
{
    if (hWnd.Equals(0))
        return;

    SendMessage(hWnd,
                (uint)WM.SYSCOMMAND,
                SC_RESTORE,
                0);
}

[DllImport("user32.dll")]
public static extern IntPtr SendMessage(IntPtr hWnd,
                                        uint msg,
                                        uint wParam,
                                        uint lParam);
于 2012-10-01T21:30:43.017 回答