c# 程序只能運行一次(多次運行只能打開同一個程序)

代碼參考: C#代碼 程序只能運行一次!

防止程序運行多個實例的方法有多種,如:通過使用互斥量和進程名等.而我想要實現的是:在程序運行多個實例時激活的是第一個實例,使其獲得焦點,並在前端顯示.

主要用到兩個API 函數:

  • ShowWindowAsync 該函數設置由不同線程產生的窗口的顯示狀態。
  • SetForegroundWindow 該函數將創建指定窗口的線程設置到前臺,並且激活該窗口。鍵盤輸入轉向該窗口,併爲用戶改各種可視的記號。系統給創建前臺窗口的線程分配的權限稍高於其他線程。

代碼如下:

  1. static class Program
  2.     {
  3.         /// <summary>
  4.         /// 該函數設置由不同線程產生的窗口的顯示狀態。
  5.         /// </summary>
  6.         /// <param name="hWnd">窗口句柄</param>
  7.         /// <param name="cmdShow">指定窗口如何顯示。查看允許值列表,請查閱ShowWlndow函數的說明部分。</param>
  8.         /// <returns>如果函數原來可見,返回值爲非零;如果函數原來被隱藏,返回值爲零。</returns>
  9.         [DllImport("User32.dll")]
  10.         private static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow);
  11.         /// <summary>
  12.         /// 該函數將創建指定窗口的線程設置到前臺,並且激活該窗口。鍵盤輸入轉向該窗口,併爲用戶改各種可視的記號。系統給創建前臺窗口的線程分配的權限稍高於其他線程。
  13.         /// </summary>
  14.         /// <param name="hWnd">將被激活並被調入前臺的窗口句柄。</param>
  15.         /// <returns>如果窗口設入了前臺,返回值爲非零;如果窗口未被設入前臺,返回值爲零。</returns>
  16.         [DllImport("User32.dll")]
  17.         private static extern bool SetForegroundWindow(IntPtr hWnd);
  18.         private const int WS_SHOWNORMAL = 1;
  19.         /// <summary>
  20.         /// 應用程序的主入口點。
  21.         /// </summary>
  22.         [STAThread]
  23.         static void Main()
  24.         {
  25.             Application.EnableVisualStyles();
  26.             Application.SetCompatibleTextRenderingDefault(false);
  27.             Process instance = RunningInstance();
  28.             if (instance == null)
  29.             {
  30.                 Form1 frm = new Form1();
  31.                 Application.Run(new Form1());
  32.             }
  33.             else
  34.             {
  35.                 HandleRunningInstance(instance);
  36.             }
  37.         }
  38.         /// <summary>
  39.         /// 獲取正在運行的實例,沒有運行的實例返回null;
  40.         /// </summary>
  41.         public static Process RunningInstance()
  42.         {
  43.             Process current = Process.GetCurrentProcess();
  44.             Process[] processes = Process.GetProcessesByName(current.ProcessName);
  45.             foreach (Process process in processes)
  46.             {
  47.                 if (process.Id != current.Id)
  48.                 {
  49.                     if (Assembly.GetExecutingAssembly().Location.Replace("/""//") == current.MainModule.FileName)
  50.                     {
  51.                         return process;
  52.                     }
  53.                 }
  54.             }
  55.             return null;
  56.         }
  57.         /// <summary>
  58.         /// 顯示已運行的程序。
  59.         /// </summary>
  60.         public static void HandleRunningInstance(Process instance)
  61.         {
  62.             ShowWindowAsync(instance.MainWindowHandle, WS_SHOWNORMAL); //顯示,可以註釋掉
  63.             SetForegroundWindow(instance.MainWindowHandle);            //放到前端
  64.         }
  65.     }

記着引用以下命名空間:
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Reflection;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章