WinForm程序,實現只啟動一個實例


前言:在我們做的軟件中,當點擊圖標運行時,正常的需求是只需要啟動一個軟件的實例,這是非常重要的一點,不然就顯得我們的軟件非常的山寨,筆者在工作中經常遇到同事沒有注意這一點,看似不重要,實則為非常的重要的一點,這里利用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 日,晚。


免責聲明!

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



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