按兩下一個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();
}
}
}

 

優點:真正能做到同一個程式只允許運行一個進程;
缺點:暫無
創作者介紹
創作者 shadow 的頭像
shadow

資訊園

shadow 發表在 痞客邦 留言(0) 人氣()