C# 实现程序只启动一次(总结)
我前面的三篇文章是从网上找到的(如下链接),都说是实现程序只启动一次的功能。
C#防止程序多次运行
C#检测程序重复运行的函数(可以在多用户登录情况下检测)
C# 实现程序只启动一次(多次运行激活第一个实例,使其获得焦点,并在最前端显示)
C# 实现程序只启动一次(实现程序自重启)
如果你已经读了前面的几篇文章,我相信你自己或许已经有答案了,我自己用下来感觉还是有一些区别的,现在把我总结的记录下来:
一:使用System.Threading.Mutex类
using (System.Threading.Mutex m = new System.Threading.Mutex(true, Application.ProductName, out createNew))
使用这个方法,我自己测试下来,在Windows的单一用户使用的时候可以使用,当多个Windows用户同时使用的时候则无法检测到程序是否在运行状态。
二:检查进程名的
Process[] processes = Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName);
使用这个方法可以检查当前机器上的所有进程名称,多个用户也可以同时检测。但是如果程序改名运行,则无法检测到程序是否在运行状态。
三:使用API
API一:
[DllImport("User32.dll")]
private static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow);
[DllImport("User32.dll")]
private static extern bool SetForegroundWindow(IntPtr hWnd);
API二:
[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
);
这个方法在我前面的文章中已经提到了两种API的使用
API一,可以使程序前端显示出来,并且获取为焦点。
API二,其实更像System.Threading.Mutex类,
因为在项目中暂时没有使用这些功能,所以没有太多的意见。
=======================================================================================
防止应用程序多开
在使用应用程序的过程中,经常要求应用程序只能运行一次。如果发现重复开启,应从系统进程列表中搜索到已经开启的进程,并将该进程窗口移到最前端显示。
记录一下过程。
实现过程
在 Program.cs 文件的 Program 类中声明两个外部调用函数
| [DllImport("User32")] | |
| private static extern bool SetForegroundWindow(IntPtr hWnd); | |
| [DllImport("User32")] | |
| private static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow); |
两个外部调用 User32.dll 文件中的函数,其中SetForegroundWindow 主要用于将窗体移动到最前端显示,ShowWindowAsync函数用于显示窗体。
修改 main 函数内容
| static void Main() | |
| { | |
| bool createdNew; //是否是第一次开启程序 | |
| Mutex mutex = new Mutex(false, "Single", out createdNew); | |
| //实例化一个进程互斥变量,标记名称Single | |
| if (!createdNew) //如果多次开启了进程 | |
| { | |
| Process currentProcess = Process.GetCurrentProcess();//获取当前进程 | |
| foreach (Process process in Process.GetProcessesByName(currentProcess.ProcessName)) | |
| { | |
| //通过进程ID和程序路径获取一个已经开启的进程 | |
| if ((process.Id != currentProcess.Id) && | |
| (Assembly.GetExecutingAssembly().Location == process.MainModule.FileName)) | |
| { | |
| //获取已经开启的进程的主窗体句柄 | |
| IntPtr mainFormHandle = process.MainWindowHandle; | |
| if (mainFormHandle != IntPtr.Zero) | |
| { | |
| ShowWindowAsync(mainFormHandle, 1); //显示已经开启的进程窗口 | |
| SetForegroundWindow(mainFormHandle); //将已经开启的进程窗口移动到前端 | |
| } | |
| } | |
| } | |
| mutex.WaitOne(); | |
| mutex.ReleaseMutex(); //释放Mutex一次 | |
| //MessageBox.Show("进程已经开启"); | |
| return; | |
| } | |
| else | |
| { | |
| Application.EnableVisualStyles(); | |
| Application.SetCompatibleTextRenderingDefault(false); | |
| Application.Run(new MainFrame()); | |
| } | |
| } |
Mutex类,该类位于System.Threading命名空间下,主要用于创建线程或进程的互斥变量。本实例创建了一个名为Single的互斥变量,在运行程序时,首先访问该互斥变量,看该变量是否已经被创建,如果已经被创建,说明已经有相同的进程正在运行。
关于 Mutex锁 :
出处:https://www.cnblogs.com/BoiledYakult/p/17148486.html
如果,您希望更容易地发现我的新博客,不妨点击一下绿色通道的【关注我】。(●'◡'●)
因为,我的写作热情也离不开您的肯定与支持,感谢您的阅读,我是【Jack_孟】!
本文来自博客园,作者:jack_Meng,转载请注明原文链接:https://www.cnblogs.com/mq0036/p/4138586.html
【免责声明】本文来自源于网络,如涉及版权或侵权问题,请及时联系我们,我们将第一时间删除或更改!
浙公网安备 33010602011771号