web-dev-qa-db-ja.com

C#.netアプリがWindowsで1つのインスタンスのみを実行するように強制するにはどうすればよいですか?

可能性のある複製:
シングルインスタンスアプリケーションを作成する正しい方法は何ですか?

C#.netアプリがWindowsで1つのインスタンスのみを実行するように強制するにはどうすればよいですか?

61
jinsungy

私は次のようなミューテックスソリューションを好みます。このように、アプリが既にロードされている場合、アプリに再び焦点を合わせます

using System.Threading;

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SetForegroundWindow(IntPtr hWnd);

/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
   bool createdNew = true;
   using (Mutex mutex = new Mutex(true, "MyApplicationName", out createdNew))
   {
      if (createdNew)
      {
         Application.EnableVisualStyles();
         Application.SetCompatibleTextRenderingDefault(false);
         Application.Run(new MainForm());
      }
      else
      {
         Process current = Process.GetCurrentProcess();
         foreach (Process process in Process.GetProcessesByName(current.ProcessName))
         {
            if (process.Id != current.Id)
            {
               SetForegroundWindow(process.MainWindowHandle);
               break;
            }
         }
      }
   }
}
104
Mitchel Sellers

.net(C#)でプログラムの1つのインスタンスのみを強制的に実行するには、program.csファイルで次のコードを使用します。

public static Process PriorProcess()
    // Returns a System.Diagnostics.Process pointing to
    // a pre-existing process with the same name as the
    // current one, if any; or null if the current process
    // is unique.
    {
        Process curr = Process.GetCurrentProcess();
        Process[] procs = Process.GetProcessesByName(curr.ProcessName);
        foreach (Process p in procs)
        {
            if ((p.Id != curr.Id) &&
                (p.MainModule.FileName == curr.MainModule.FileName))
                return p;
        }
        return null;
    }

そして次のこと:

[STAThread]
    static void Main()
    {
        if (PriorProcess() != null)
        {

            MessageBox.Show("Another instance of the app is already running.");
            return;
        }
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form());
    }
23
snir

これは私のアプリケーションで使用するものです:

static void Main()
{
  bool mutexCreated = false;
  System.Threading.Mutex mutex = new System.Threading.Mutex( true, @"Local\slimCODE.slimKEYS.exe", out mutexCreated );

  if( !mutexCreated )
  {
    if( MessageBox.Show(
      "slimKEYS is already running. Hotkeys cannot be shared between different instances. Are you sure you wish to run this second instance?",
      "slimKEYS already running",
      MessageBoxButtons.YesNo,
      MessageBoxIcon.Question ) != DialogResult.Yes )
    {
      mutex.Close();
      return;
    }
  }

  // The usual stuff with Application.Run()

  mutex.Close();
}
9
Martin Plante

アプリケーションを単一インスタンスにする別の方法は、ハッシュの合計を確認することです。ミューテックスをいじくり回した後(私は望むようには動作しませんでした)、私はそれをこのように動作させました:

    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool SetForegroundWindow(IntPtr hWnd);

    public Main()
    {
        InitializeComponent();

        Process current = Process.GetCurrentProcess();
        string currentmd5 = md5hash(current.MainModule.FileName);
        Process[] processlist = Process.GetProcesses();
        foreach (Process process in processlist)
        {
            if (process.Id != current.Id)
            {
                try
                {
                    if (currentmd5 == md5hash(process.MainModule.FileName))
                    {
                        SetForegroundWindow(process.MainWindowHandle);
                        Environment.Exit(0);
                    }
                }
                catch (/* your exception */) { /* your exception goes here */ }
            }
        }
    }

    private string md5hash(string file)
    {
        string check;
        using (FileStream FileCheck = File.OpenRead(file))
        {
            MD5 md5 = new MD5CryptoServiceProvider();
            byte[] md5Hash = md5.ComputeHash(FileCheck);
            check = BitConverter.ToString(md5Hash).Replace("-", "").ToLower();
        }

        return check;
    }

プロセスIDによるmd5合計のみをチェックします。

このアプリケーションのインスタンスが見つかった場合、実行中のアプリケーションに焦点を合わせて終了します。

名前を変更するか、ファイルで必要な処理を実行できます。 md5ハッシュが同じ場合、2回開かれません。

誰かがそれを提案するかもしれませんか?私はそれが答えられていることを知っていますが、おそらく誰かがミューテックスの代替を探しています。

2
Thyrador