用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
 }
}

posted @ 2005-08-25 23:46  瑞德船长  阅读(3105)  评论(0编辑  收藏  举报