經常我們希望一個程式開啟了以後,不希望開啟另一個執行個體。經過摸索,發現在有兩個方法可以解決,一個是通過進程,另一個是對過互 Mutex 類。
1、使用 Mutex , Mutex 中有個輸出參數可以標誌是否為新開啟的實列,我們通過這個參數來處理。
using System;
using System.Threading;
public class Test
{
public static void Main()
{
// Set this variable to false if you do not want to request
// initial ownership of the named mutex.
bool requestInitialOwnership = true;
bool mutexWasCreated;
// Request initial ownership of the named mutex by passing
// true for the first parameter. Only one system object named
// "MyMutex" can exist; the local Mutex object represents
// this system object. If "MyMutex" is created by this call,
// then mutexWasCreated contains true; otherwise, it contains
// false.
Mutex m = new Mutex(requestInitialOwnership, "MyMutex", out mutexWasCreated);
// This thread owns the mutex only if it both requested
// initial ownership and created the named mutex. Otherwise,
// it can request the named mutex by calling WaitOne.
if (!(requestInitialOwnership && mutexWasCreated))
{
Console.WriteLine("Waiting for the named mutex.");
m.WaitOne();
}
// Once the process has gained control of the named mutex,
// hold onto it until the user presses ENTER.
Console.WriteLine("This process owns the named mutex. " +"Press ENTER to release the mutex and exit.");
Console.ReadLine();
// Call ReleaseMutex to allow other threads to gain control
// of the named mutex. If you keep a reference to the local
// Mutex, you can call WaitOne to request control of the
// named mutex.
m.ReleaseMutex();
}
}
2 通過進程
在進程池中尋找當前的進程名的進程。根據是否能找到來處理。下面的例子,先判斷是否已經開啟,如果開啟就把已經開啟的設定最大化,新程式不運行。(下面為WINFORM程式)
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace WinTest
{
/// <summary>
/// Program 的摘要說明。
/// </summary>
public class Program1
{
#region 應用程式的主進入點。
[STAThread]
static void Main()
{
mainForm mainForm = new mainForm();
Process instance = RunningInstance();
if (instance == null)
{
Application.Run(mainForm);
}
else
{
HandleRunningInstance(instance);
}
}
private static Process RunningInstance()
{
Process current = Process.GetCurrentProcess();
Process[] processes = Process.GetProcessesByName(current.ProcessName);
//遍曆正在有相同名字啟動並執行常式
foreach (Process process in processes)
{
//忽略現有的常式
if (process.Id != current.Id)
{
//確保常式從EXE檔案運行
if (Assembly.GetExecutingAssembly().Location.Replace("/", "\\\\") ==
current.MainModule.FileName)
{
//返回另一個常式執行個體
return process;
}
}
}
//沒有其它的常式,返回Null
return null;
}
private const int WS_SHOWNORMAL = 1; //winuser.h define
private static void HandleRunningInstance(Process instance)
{
//確保視窗沒有被最小化或最大化
ShowWindowAsync(instance.MainWindowHandle, WS_SHOWNORMAL);
//設定真執行個體程為foreground window
SetForegroundWindow(instance.MainWindowHandle);
}
[DllImport("User32.dll")]
private static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow);
[DllImport("User32.dll")]
private static extern bool SetForegroundWindow(IntPtr hWnd);
#endregion
}
}