怎么讓C#程序同時只能運行一個實例


雙擊一個WinForm程序,會打開一個界面,也即運行了一個程序的實例;雙擊多次的時候,會出現多個程序界面。有時候我們需要只允許程序只能同時運行一個實例。實現方式有很多。

一.   進程互斥

原理:通過獲取系統進程列表,如果發現有重名的,則表示程序已經運行了,此時新運行的進程就退出;

實現:System.Diagnostics.Process類的靜態方法GetProcessesByName(string processName)

Process[] ps = Process.GetProcessesByName("Guo.exe");

if (ps != null && ps.Length > 1)

{

   //發現重復進程

}

寫在Main方法里;判斷Length大於1,是因為本身啟動之后也在進程列表里了,第一次啟動的時候Length==1;

優點:代碼簡單;

缺點:會把別的重名程序誤認為是自己(如很多軟件都有update.exe);可以通過復制多個exe並起不同名字來達到運行多個實例的目的;

二.   共享鎖(文件、注冊表)

原理:運行程序時,在一個公共的位置創建一個共享值(如在固定目錄創建一個文件,或者在固定的注冊表位置創建一個值),退出程序時刪除該值。若運行時發現值已經在,則表示程序已經在運行,此時新運行的進程就退出;

實現:略;

優點:邏輯好理解;

缺點:若程序沒有正常退出,共享值沒有被刪除,會導致程序無法再啟動;

三.   線程互斥

原理:通過一個唯一標識創建進程互斥體,啟動時判斷互斥體是否已經存在,若存在則表示是重復進程;

實現:使用System.Threading.Mutex

using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.InteropServices;

namespace ConsoleApplication1
{
    class Program
    {
        /// <summary>
        /// 需要定義為類變量,而非局部變量
        /// </summary>
        static System.Threading.Mutex _mutex;

        static void Main(string[] args)
        {
            //是否可以打開新進程
            bool createNew;
            
            //獲取程序集Guid作為唯一標識
            Attribute guid_attr = Attribute.GetCustomAttribute(Assembly.GetExecutingAssembly(), typeof(GuidAttribute));
            string guid = ((GuidAttribute)guid_attr).Value;
            _mutex = new System.Threading.Mutex(true, guid, out createNew);
            if (false == createNew)
            {
                //發現重復進程
            }
            _mutex.ReleaseMutex();
        }
    }
}

優點:真正能做到同一個程序只允許運行一個進程;

缺點:暫無

注意:如果用不同用戶同時登陸windows,仍然可以各自運行一個實例;如果想要不同用戶也只能運行一個實例,那么,上面的guid變量需要加上前綴“Global\\”,詳細可參看http://www.csharpwin.com/csharpspace/12748r5312.shtml


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM