方法一
class Program { [STAThread] static void Main(string[] args) { //防止程序多次運行 if (!OneInstance.IsFirst("MyTest")) { Console.WriteLine("警告:程序正在運行中! 請不要重復打開程序!可在右下角系統欄找到!"); return; } Console.WriteLine("正在運行中"); Console.ReadLine(); } } public static class OneInstance { ///<summary> ///判斷程序是否正在運行 ///</summary> ///<param name="appId">程序名稱</param> ///<returns>如果程序是第一次運行返回True,否則返回False</returns> public static bool IsFirst(string appId) { bool ret = false; if (OpenMutex(0x1F0001, 0, appId) == IntPtr.Zero) { CreateMutex(IntPtr.Zero, 0, appId); ret = true; } return ret; } [DllImport("Kernel32.dll", CharSet = CharSet.Auto)] private static extern IntPtr OpenMutex( uint dwDesiredAccess, // access int bInheritHandle, // inheritance option string lpName // object name ); [DllImport("Kernel32.dll", CharSet = CharSet.Auto)] private static extern IntPtr CreateMutex( IntPtr lpMutexAttributes, // SD int bInitialOwner, // initial owner string lpName // object name ); }
方法二
string MnName = Process.GetCurrentProcess().MainModule.ModuleName; //返回不具有擴展名的制定路徑字符串的文件名String Pname = Path.GetFileNameWithoutExtension(MnName);Process[] myprocess = Process.GetProcessesByName(Pname);if (myprocess.Length > 1){ MessageBox.Show("yici", "tishi", MessageBoxButtons.OK, MessageBoxIcon.Information);}else{ //Application.EnableVisualStyles(); ////Application.SetCompatibleTextRenderingDefault(false); //Application.Run(new Form1());}
方法三
原文如下(//www.49028c.com/article/41179.htm)
經常我們會有這樣的需求,只讓應用程序運行一個實體。通常我們的情況是,雙擊一個exe文件,就運行一個程序的實體,再雙擊一次這個exe文件,又 運行這個應用程序的另一個實體。就拿QQ游戲來說吧,一臺電腦上一般只能運行一個QQ游戲大廳(不過以前聽說過有雙開的外掛)。
那我們的程序也能像QQ游戲那里禁止多次啟動嗎,答案是可以的,下面介紹下一個簡單的實現方法,那就是Mutex(互斥)。
Mutex(mutual exclusion,互斥)是.Net Framework中提供跨多個線程同步訪問的一個類。它非常類似了Monitor類,因為他們都只有一個線程能擁有鎖定。而操作系統能夠識別有名稱的互 斥,我們可以給互斥一個唯一的名稱,在程序啟動之前加一個這樣的互斥。這樣每次程序啟動之前,都會檢查這個命名的互斥是否存在。如果存在,應用程序就退 出。
static class Program { /// <summary> /// The main entry point for the application. /// </summary> [STAThread] static void Main() { bool createdNew; //系統能夠識別有名稱的互斥,因此可以使用它禁止應用程序啟動兩次 //第二個參數可以設置為產品的名稱:Application.ProductName //每次啟動應用程序,都會驗證名稱為SingletonWinAppMutex的互斥是否存在 Mutex mutex = new Mutex(false, "SingletonWinAppMutex", out createdNew); //如果已運行,則在前端顯示 //createdNew == false,說明程序已運行 if (!createdNew) { Process instance = GetExistProcess(); if (instance != null) { SetForegroud(instance); Application.Exit(); return; } } Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new MainForm()); } /// <summary> /// 查看程序是否已經運行 /// </summary> /// <returns></returns> private static Process GetExistProcess() { Process currentProcess = Process.GetCurrentProcess(); foreach (Process process in Process.GetProcessesByName(currentProcess.ProcessName)) { if ((process.Id != currentProcess.Id) && (Assembly.GetExecutingAssembly().Location == currentProcess.MainModule.FileName)) { return process; } } return null; } /// <summary> /// 使程序前端顯示 /// </summary> /// <param name="instance"></param> private static void SetForegroud(Process instance) { IntPtr mainFormHandle = instance.MainWindowHandle; if (mainFormHandle != IntPtr.Zero) { ShowWindowAsync(mainFormHandle, 1); SetForegroundWindow(mainFormHandle); } } [DllImport("User32.dll")] private static extern bool SetForegroundWindow(IntPtr hWnd); [DllImport("User32.dll")] private static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow); }
經過我的測試,還比較好用,但是有個問題,如果不注銷,用另一個用戶進入,則程序不能判斷出已運行。所以只限于用在單用戶環境,還是不太完美。
class Program { [STAThread] static void Main(string[] args) { //防止程序多次運行 if (!OneInstance.IsFirst("MyTest")) { Console.WriteLine("警告:程序正在運行中! 請不要重復打開程序!可在右下角系統欄找到!"); return; } Console.WriteLine("正在運行中"); Console.ReadLine(); } } public static class OneInstance { ///<summary> ///判斷程序是否正在運行 ///</summary> ///<param name="appId">程序名稱</param> ///<returns>如果程序是第一次運行返回True,否則返回False</returns> public static bool IsFirst(string appId) { bool ret = false; if (OpenMutex(0x1F0001, 0, appId) == IntPtr.Zero) { CreateMutex(IntPtr.Zero, 0, appId); ret = true; } return ret; } [DllImport("Kernel32.dll", CharSet = CharSet.Auto)] private static extern IntPtr OpenMutex( uint dwDesiredAccess, // access int bInheritHandle, // inheritance option string lpName // object name ); [DllImport("Kernel32.dll", CharSet = CharSet.Auto)] private static extern IntPtr CreateMutex( IntPtr lpMutexAttributes, // SD int bInitialOwner, // initial owner string lpName // object name ); }
新聞熱點
疑難解答