先解释一下需求,假如我们开发了一个程序叫做QQ.exe,在QQ.exe启动之后,我们不允许QQ.exe再次启动,那么我们该如何做呢?
下面我们用一个很简单的程序模拟QQ.exe来实现这个需求。
启动VS创建一个控制台应用程序,编辑如下代码:
1 using System.Runtime.InteropServices; 2 using System.Windows.Forms; 3 4 public class Program 5 { 6 public static void Main() 7 { 8 FreeConsole(); 9 MessageBox.Show(" 开始运行!", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Information); 10 } 11 12 [DllImport("kernel32.dll")] 13 public static extern bool FreeConsole(); 14 }
生成exe文件:
我们多次点击生成的CSharp.exe会出现如下情况:
那么我们如何做可以限制CSharp.exe只启动一次呢?
下面是改进后的代码:
1 using System; 2 using System.Diagnostics; 3 using System.Runtime.InteropServices; 4 using System.Windows.Forms; 5 6 public class Program 7 { 8 public static void Main() 9 { 10 Process pro = RunningProcessInstance(); 11 if (null != pro) 12 { 13 FreeConsole(); 14 MessageBox.Show(pro.MainModule.FileName + " 已经运行!", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Information); 15 ShowWindowAsync(pro.MainWindowHandle, 1); 16 SetForegroundWindow(pro.MainWindowHandle); 17 } 18 else 19 { 20 FreeConsole(); 21 SetForegroundWindow(Process.GetCurrentProcess().MainWindowHandle); 22 MessageBox.Show(" 开始运行!", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Information); 23 } 24 } 25 26 static Process RunningProcessInstance() 27 { 28 Process curPro = Process.GetCurrentProcess(); 29 string curFileName = curPro.MainModule.FileName; 30 string proName = curPro.ProcessName; 31 Process[] processes = Process.GetProcessesByName(proName); 32 foreach (Process pro in processes) 33 { 34 if (pro.Id != curPro.Id && pro.MainModule.FileName == curFileName) 35 { 36 return pro; 37 } 38 } 39 40 return null; 41 } 42 43 [DllImport("kernel32.dll")] 44 public static extern bool FreeConsole(); 45 [DllImport("User32.dll")] 46 private static extern bool ShowWindowAsync(System.IntPtr hWnd, int cmdShow); 47 [DllImport("User32.dll")] 48 private static extern bool SetForegroundWindow(System.IntPtr hWnd); 49 }
再次执行的:
只有在第一次执行的时候,会弹出开始运行的提示,后面的运行将出现“已运行”的提示。
但是要注意,假如我们将exe文件放在不同的目录下,这个将代表着不同的程序。
新建目录a和b,然后将CSharp.exe分别拷贝进去一份,我们分别执行的结果: