http://expert.csdn.net/Expert/topic/2491/2491081.xml?temp=.2268488

解决方案 »

  1.   

    程序初始化的时候,监测当前进程列表,判断如果程序已经运行,则退出程序,并转到该程序的存在实例即可Process[] myProcesses;
    // Returns array containing all instances of Notepad.
    myProcesses = Process.GetProcessesByName("Notepad");if (myProcesses[0]!=null)
    //退出语句
      

  2.   

    using System;
    using System.Runtime.InteropServices;
    using System.Windows.Forms;
    using System.Diagnostics;
    using System.Reflection; public class OneInstnace
     { 
     [STAThread]
     public static void Main()
     {
     //Get the running instance.
     Process instance = RunningInstance();
     if (instance == null)
     {
     //There isn't another instance, show our form.
     Application.Run (new Form());
     }
     else
     {
     //There is another instance of this process.
     HandleRunningInstance(instance);
     }
     }
     public static Process RunningInstance()
     {
     Process current = Process.GetCurrentProcess();
     Process[] processes = Process.GetProcessesByName (current.ProcessName);
     //Loop through the running processes in with the same name
     foreach (Process process in processes)
     {
     //Ignore the current process
     if (process.Id != current.Id)
     {
     //Make sure that the process is running from the exe file.
     if (Assembly.GetExecutingAssembly().Location.Replace("/", "\\") == current.MainModule.FileName)
     {
     //Return the other process instance.
     return process;
     }
     }
     }
      

  3.   

    [STAThread]
    static void Main() 
    {
    bool runOne; gM1 = new Mutex(true,"MyNotifyDemo");

    runOne=gM1.WaitOne(10,true); if (runOne==false)  //已经有一个实例在运行
    {
    MessageBox.Show("图标已经添加!","提示信息",MessageBoxButtons.OK,MessageBoxIcon.Warning);

    return;
    }
    Application.Run(new Form1());

    gM1.ReleaseMutex( );
    }另外,你可以通过对一个端口进行绑定,也可以实现只运行一个实例.
      

  4.   

    上面的方法能在你对EXE文件改名后,仍可以实现只运行一个实例.
      

  5.   

    谢谢各位大哥,谢谢acewang(),使用你的方法搞定了^_^,结贴。
      

  6.   

    有时你会想只运行一个程序首次运行时的实例,有些时候则可能只需要运行最新的那个实例。以下是这两种实现这两种方法的例子。
    你如何才能确保只有一个.NET的程序运行在你的机器上呢?多任务操作系统在很多方面都很有用,但是有时你只需要在某一时间内运行一个实例,例如,如果程序需要使用很多的资源或者需要排它地存取某一个资源。在这种情况下,你可能想确认当另一个实例启动时,它会检查是否有另一个实例正在运行。如果是,则将自身关闭。本文中,我会告诉大家如何去实现它,还有在相关的情况下如何只允许最新的程序实例运行。请在以下地址下载程序源码ftp://ftp.wdj.com/pub/webzip/newsletters/20030815dnn.zip
    最简单的方法是使用mutex对像。例如,在以下的代码中,Form的构造函数中创建了一个mutex对象,然后 试着去存取它。如果WaitOne()返回true,那么当前线程就已经拥有了mutex,如果返回false则mutex已经被另一个线程所拥有。using System;using System.Windows.Forms;using System.Threading; class App : Form{     Mutex mutex;     App()     {         Text = "Single Instance!";         mutex = new Mutex(false, "SINGLE_INSTANCE_MUTEX");         if (!mutex.WaitOne(0, false))          {              mutex.Close();              mutex = null;         }     }     protected override void Dispose(bool disposing)     {         if (disposing)              mutex.ReleaseMutex();         base.Dispose(disposing);     }     static void Main()     {         App app = new App();         if (app.mutex != null) Application.Run(app);         else MessageBox.Show("Instance already running");     }}在以上代码中,方法Dispose()并不严格需要,这是因为当程序结束时,垃圾回收器将会dispose并且release mutex对象。但是我仍然添加了它,这是因为Form需要一段很长的时间来释放(dispose),并且另一个窗体(Form)的实例将会启动。 
    这种方法只允许第一个进程实例运行。但如果你只想运行最新的那个实例时怎么办呢?就是说如果我启动了一个新的进程实例,而且之前已经有一个实例正在运行中,那么我们需要停止之前的那个线程。例如屏保的显示属性对话框。这个对话框显示一个小的预览窗口,当用用户点击预览按钮时,另一个屏保程序实例(instance)就会启动并全屏显示。当全屏实例停止时(例如你移动了鼠标),另一个屏保实例就会开始在小的预览窗口中开始运行。很明显,当全屏实例开始,这个预览的屏保窗口进程就要结束。 一种实现的方法是为每一个实例去存取一个命名的事件核心对象(named event kernel object),如果事件对象没有被触发(nonsignaled),那么此实例就继续运行;如果事件被触发则程序实例会结束。应用程序可以周期性地测试事件去看是否它已经被触发。当一个新的实例启动,它就会设置事件(去关闭其它任何实例)然后重设事件以使它可以继续运行。这种方案除了一个小问题外运行良好:.NET Framework不会允许你命名一个核心事件(kernel event)。以下是一个实现的类     public class NamedEventHelper     {         [DllImport("kernel32")]         static extern uint CreateEvent(              uint sec, bool manualReset, bool initialState, string name);         static IntPtr CreateEvent(bool manualReset, bool initialState, string name)         {              return new IntPtr(CreateEvent(0, manualReset, initialState, name));         }         [DllImport("kernel32")]         static extern bool CloseHandle(IntPtr handle);         public static ManualResetEvent CreateNamedEvent(              bool initialState, string name)         {              ManualResetEvent mre = new ManualResetEvent(false);              CloseHandle(mre.Handle);              mre.Handle = CreateEvent(true, initialState, name);              return mre;         }     } 以上的代码中,静态(static)方法CreateNamedEvent()创建了一个ManualResetEvent对象,并释放了当前的(underlying)Win32句柄(handle)。然后再创建一个命名事件(named event)并且使用此新事件的句柄初始化了ManualResetEvent对象。此事件对象就能被用于两个应用程序间的通信。  这种方案的弱点是一个应用程序一定要看它是否已经结束。一种解决方法是运行一个后台线程去管理事件      ManualResetEvent mre;     mre = NamedEventHelper.CreateNamedEvent(false, "LAST_INSTANCE_ONLY");     // Stop the other instances     mre.Set();     // Reset the event so that we can run     mre.Reset();     // Create a monitor thread     Thread t = new Thread(new ThreadStart(Monitor));     // Make sure that this thread cannot keep the app alive     t.IsBackground = true;     t.Start();      //The Monitor() method looks like this:      void Monitor()     {         mre.WaitOne();         Application.Exit();     } 如果程序有一个窗体,那么另一种方法就是告诉其它窗口去关闭这个新的程序实例。如果这是一个Win32应用程序,那么此程序可以简单地通过调用FindWindowsEx(),并传入一个特定的窗口类参数,然后发送WM_CLOSE消息。但是你不能对Windows Form这样做 ,因为大多数窗体(Forms)都有相同的类名,正如我在上一封newsletter是所说的。在下一个newsletter中,我会解释另一种方法去解决这类问题。
      

  7.   

    http://expert.csdn.net/Expert/topic/2572/2572209.xml?temp=.2559931