用Mutex或进程限制用户在一台电脑上同时打开两个程序
经常我们希望一个程序打开了以后,不希望打开另一个实例。经过摸索,发现在有两个方法可以解决,一个是通过进程,另一个是对过互 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
}
}