1

私のアプリには、コンピューターの起動時にアイコン トレイで実行するデフォルト設定があります。アイコン トレイからアイコンをクリックすると、アプリがデスクトップ ウィンドウに表示されます。さらに、ユーザーが古いアプリの実行中にアプリの新しいインスタンスを起動しようとすると、別のインスタンスが実行されているというメッセージを表示してから、新しいインスタンスを終了します。

ここで、New インスタンスを終了するだけでなく、Old インスタンスをアクティブにしてデスクトップに表示したいと考えています。これは私の現在のコードです

if (System.Diagnostics.Process.GetProcessesByName(
           System.Diagnostics.Process.GetCurrentProcess().ProcessName).Length > 1)
{
    MessageBox.Show(kingCobra.Properties.Resources.Msg_Multiple_Starts, 
                    kingCobra.Properties.Resources.Multiple_Starts,
                    MessageBoxButtons.OK, MessageBoxIcon.Warning);
    System.Diagnostics.Process.GetCurrentProcess().Kill();
    return;
}
4

4 に答える 4

2

あなたがする必要があるのは、これをメインクラスに追加することです:

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

次に、既に実行中のプロセスへの参照を取得し、次のように SetForegroundWindow メソッドを呼び出す必要があります。

  SetForegroundWindow(SameProcess.MainWindowHandle);

現在行っているように現在のプロセスを強制終了する必要はありません。上記のように、他のプロセスのメイン ウィンドウにフォーカスした後に戻るだけです。

これは完全に機能する例です:

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


/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
    var currentProcess = Process.GetCurrentProcess();

    foreach (Process p in Process.GetProcessesByName(currentProcess.ProcessName))
    {
        if (p.Id != currentProcess.Id)
        {
            MessageBox.Show("Already running");
            SetForegroundWindow(p.MainWindowHandle);
            return;
        }
    }

    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new Form1());
}
于 2013-08-29T11:54:48.933 に答える
1

I finally Got what I wanted from Here. My main problem was to bring the old instance from the Icon tray whilst closing the new

 static class Program
{
    [STAThread]
    static void Main()
    {
        if (!SingleInstance.Start()) {
            SingleInstance.ShowFirstInstance();
            return;
        }

    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);

    try {
        MainForm mainForm = new MainForm();
        Application.Run(mainForm);
    } catch (Exception e) {
        MessageBox.Show(e.Message);
    }

    SingleInstance.Stop();
}
} 
//And secondly within your main form, the following code must be added:

protected override void WndProc(ref Message message)
{
    if (message.Msg == SingleInstance.WM_SHOWFIRSTINSTANCE) {
        Show

Window();
    }
    base.WndProc(ref message);
} 

public void ShowWindow()
{
    // Insert code here to make your form show itself.
    WinApi.ShowToFront(this.Handle);
}
于 2013-09-11T02:25:18.930 に答える
0

Threading Mutex と user32.dll を使用できます

これを試して

ステップ 1 : 次の定数を宣言します。

private const int SW_NORMAL = 1; // see WinUser.h for definitions
private const int SW_SHOWMAXIMIZED = 3;
private const int SW_RESTORE = 9;

[DllImport("User32", EntryPoint = "FindWindow")]
static extern IntPtr FindWindow(string className, string windowName);

[DllImport("User32", EntryPoint = "SendMessage")]
private static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

[DllImport("User32", EntryPoint = "SetForegroundWindow")]
private static extern bool SetForegroundWindow(IntPtr hWnd);

[DllImport("User32", EntryPoint = "SetWindowPlacement")]
private static extern bool SetWindowPlacement(IntPtr hWnd, [In] ref WINDOWPLACEMENT lpwndpl);

[DllImport("User32", EntryPoint = "GetWindowPlacement")]
private static extern bool GetWindowPlacement(IntPtr hWnd, [In] ref WINDOWPLACEMENT lpwndpl);


private struct WINDOWPLACEMENT
{
    public int length;
    public int flags;
    public int showCmd;
}

ステップ 2: このメソッドを追加します。

public void application_run(Form form1)
{
bool createdNew;

            System.Threading.Mutex m = new System.Threading.Mutex(true, form1.Name, out createdNew);
            if (!createdNew)
            {
                MessageBox.Show("...", "...", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);//Alert message

                try
                {
                    // see if we can find the other app and Bring it to front
                    IntPtr hWnd = FindWindow(null, form1.Text);
                    if (hWnd != IntPtr.Zero)
                    {
                        LoaderDomain.WINDOWPLACEMENT placement = new LoaderDomain.WINDOWPLACEMENT();
                        placement.length = Marshal.SizeOf(placement);
                        GetWindowPlacement(hWnd, ref placement);
                        placement.showCmd = SW_SHOWMAXIMIZED;
                        SetWindowPlacement(hWnd, ref placement);
                        SetForegroundWindow(hWnd);
                    }
                }
                catch 
                {
                    //rien
                }

            }
            else
            {
                Application.Run(form1);
            }
            // keep the mutex reference alive until the normal termination of the program
            GC.KeepAlive(m);

}

ステップ 3 : メインで交換する

Application.run(forms);

前のメソッドへの呼び出しによって

于 2013-08-29T12:02:03.997 に答える