前言:在我們做的軟件中,當點擊圖標運行時,正常的需求是只需要啟動一個軟件的實例,這是非常重要的一點,不然就顯得我們的軟件非常的山寨,筆者在工作中經常遇到同事沒有注意這一點,看似不重要,實則為非常的重要的一點,這里利用C#實現單實例的模式。
注:代碼需寫在Program.cs中,具體代碼如下:
1 static class Program 2 { 3 4 /// <summary> 5 /// 該函數設置由不同線程產生的窗口的顯示狀態。 6 /// </summary> 7 /// <param name="hWnd">窗口句柄</param> 8 /// <param name="cmdShow">指定窗口如何顯示。查看允許值列表,請查閱ShowWlndow函數的說明部分。</param> 9 /// <returns>如果函數原來可見,返回值為非零;如果函數原來被隱藏,返回值為零。</returns> 10 [DllImport("User32.dll")] 11 private static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow); 12 /// <summary> 13 /// 該函數將創建指定窗口的線程設置到前台,並且激活該窗口。鍵盤輸入轉向該窗口,並為用戶改各種可視的記號。系統給創建前台窗口的線程分配的權限稍高於其他線程。 14 /// </summary> 15 /// <param name="hWnd">將被激活並被調入前台的窗口句柄。</param> 16 /// <returns>如果窗口設入了前台,返回值為非零;如果窗口未被設入前台,返回值為零。</returns> 17 [DllImport("User32.dll")] 18 private static extern bool SetForegroundWindow(IntPtr hWnd); 19 private const int WS_SHOWMAXIMIZE = 3; //最大化顯示窗口 20 private const int WS_SHOW = 5;//以原來大小和位置顯示 21 22 23 /// <summary> 24 /// 應用程序的主入口點。 25 /// </summary> 26 [STAThread] 27 static void Main() 28 { 29 Application.EnableVisualStyles(); 30 Application.SetCompatibleTextRenderingDefault(false); 31 32 Process instance = RunningInstance(); 33 34 if (instance == null) 35 { 36 LoginForm lf = new LoginForm(); 37 lf.ShowDialog(); 38 if (lf.DialogResult == DialogResult.OK) 39 Application.Run(new SelectItemForm()); 40 } 41 else 42 { 43 HandleRunningInstance(instance); 44 45 } 46 47 } 48 49 50 /// <summary> 51 /// 獲取正在運行的實例,沒有運行的實例返回null; 52 /// </summary> 53 public static Process RunningInstance() 54 { 55 Process current = Process.GetCurrentProcess(); 56 Process[] processes = Process.GetProcessesByName(current.ProcessName); 57 foreach (Process process in processes) 58 { 59 if (process.Id != current.Id) 60 { 61 if (process.MainModule.FileName == current.MainModule.FileName) 62 { 63 return process; 64 } 65 } 66 } 67 return null; 68 } 69 70 /// <summary> 71 /// 顯示已運行的程序。 72 /// </summary> 73 public static void HandleRunningInstance(Process instance) 74 { 75 if (CONSTANTDEFINE.LOGIN == 1) //筆者這里根據實際情況,進行了控制 76 ShowWindowAsync(instance.MainWindowHandle, WS_SHOWMAXIMIZE); //顯示,通過后面的值可以對窗口大小進行控制 77 else 78 ShowWindowAsync(instance.MainWindowHandle, WS_SHOW); 79 80 SetForegroundWindow(instance.MainWindowHandle); //放到前端 81 } 82 }
通過以上代碼,就可以實現,程序只啟動一次,而不是每次點擊都會進行一個實例化。
by Shawn Chen,2017.7.10 日,晚。