3

私はこれに1つの問題がありますか?!私はこの方法を使用して、プログラムの1つのインスタンスのみを実行します。とても良いですが、他のアプリでこのように使うと。デスクトップからショートカットを介してそれらのプログラムの1つを実行すると、両方のプログラムが呼び出され、デスクトップに表示されます。注:両方のプログラムはWindowsシステムで実行されます。

    static bool ok;
    static Mutex mutex = new Mutex(true, "{123Newsoft-Cleaner Portable Program123}",out ok);

    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]

    static void Main()
    {
        //Application.EnableVisualStyles();
        //Application.SetCompatibleTextRenderingDefault(false);
        //Application.Run(new Form1());

        if (mutex.WaitOne(TimeSpan.Zero, true))  
        {

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


            var mainForm = new Form1c();

            try
            {                                    

                    mainForm.Visible = false;


                    mainForm.WindowState = FormWindowState.Normal;                  

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            Application.Run(mainForm);               

        }
        else
        {

            NativeMethods.PostMessage((IntPtr)NativeMethods.HWND_BROADCAST, NativeMethods.WM_SHOWME, IntPtr.Zero, IntPtr.Zero);

        }

//----------------メインフォーム

    protected override void WndProc(ref Message M_C)
    {

        if (M_C.Msg == NativeMethods.WM_SHOWME)
        {               
            ShowMe();
        }
        base.WndProc(ref M_C);
    }

    //*************
    private void ShowMe()
    {

        if (WindowState == FormWindowState.Minimized)
        {
            Show();
            WindowState = FormWindowState.Normal;
        }

        // get our current "TopMost" value (ours will always be false though)
        bool top = TopMost;
        // make our form jump to the top of everything
        TopMost = true;
        // set it back to whatever it was
        TopMost = top;

    }  
4

2 に答える 2

11

これは、.NET Framework によって既に十分にサポートされています。WindowsFormsApplicationBase クラスを使用します。IsSingleInstance プロパティを true に設定します。OnStartupNextInstance メソッドをオーバーライドして、別のインスタンスが開始されたときに好きなことを行うことができます。最初のインスタンスのウィンドウを復元するように。Program.cs ファイルを次のように書き換えます。

using System;
using System.Windows.Forms;
using Microsoft.VisualBasic.ApplicationServices;   // Add reference to Microsoft.VisualBasic

namespace WindowsFormsApplication1 {
    class Program : WindowsFormsApplicationBase {
        [STAThread]
        static void Main(string[] args) {
            var app = new Program();
            app.Run(args);
        }
        public Program() {
            this.IsSingleInstance = true;
            this.EnableVisualStyles = true;
            this.MainForm = new Form1();
        }
        protected override void OnStartupNextInstance(StartupNextInstanceEventArgs eventArgs) {
            if (this.MainForm.WindowState == FormWindowState.Minimized) this.MainForm.WindowState = FormWindowState.Normal;
            this.MainForm.Activate();
        }
    }
}
于 2012-08-12T16:49:58.533 に答える
1

Hans Passant の記述に追加するために、ウィンドウの復元とアクティブ化を処理するメソッドをメイン フォームに追加しました。これは、フォームの呼び出し必須条件をラップするためでした。

したがって、フォームに追加されたメソッドは次のとおりです。

/// <summary>
/// Recovers this instance of the form.
/// </summary>
public void RestoreFromTray()
{
   if(this.InvokeRequired)
   {
      this.Invoke(new Action(RestoreFromTray) );
      return;
   }
   this.Visible = true;
   this.WindowState = FormWindowState.Normal;
   this.Activate();
}

次に、ハンスの方法で、オーバーライドを次のように単純に変更しました。

protected override void OnStartupNextInstance(StartupNextInstanceEventArgs eventArgs) 
{
    ((formClassName)this.MainForm).RestoreFromTray();
}

ここで、formClassName はフォームのクラス名です。

于 2016-08-16T19:24:17.800 に答える