1

同じアプリケーションの 2 番目のインスタンスが起動したときに、システム トレイからウィンドウを復元して最大化するタスクに取り組んでいます。

2 番目のインスタンスが起動し、ミューテックスの取得に失敗した場合。次のコードを呼び出して、最初のインスタンスに自分自身を表示するよう通知します。

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 に答える