防止.NET应用多实例运行的有效方法
核心思路
1、检查是否已有程序实例运行
使用 System.Diagnostics.Process
获取当前程序进程,并与系统中所有同名的程序进程进行比较。如果发现另一个同名进程,则认为程序已经运行。
2、激活已运行的程序窗口
如果发现已有实例运行,使用 Win32 API
操作将其窗口置于前台,避免用户启动多个实例。
3、运行主程序逻辑
如果没有其他实例运行,正常启动主程序。
代码解析
1、检查是否已有程序运行
以下代码通过进程名称筛选当前运行的程序进程列表,返回除当前进程外的其他同名进程(如果存在):
public static Process GetExistProcess() { Process currentProcess = Process.GetCurrentProcess(); // 当前程序 foreach (Process process in Process.GetProcessesByName(currentProcess.ProcessName)) { if (process.Id != currentProcess.Id) // 找到其他同名进程 { return process; // 返回已运行的进程 } } return null; // 没有其他实例 }
2、主程序入口
在 Main
方法中调用 GetExistProcess
检查程序实例:
static class Program { [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); var runningProcess = GetExistProcess(); if (runningProcess != null) // 如果有实例运行 { IntPtr mainWindowHandle = runningProcess.MainWindowHandle; if (mainWindowHandle == IntPtr.Zero) // 窗口被隐藏 { mainWindowHandle = FindWindow(null, "唯一程序"); } ShowWindowAsync(mainWindowHandle, 1); // 显示窗口 SetForegroundWindow(mainWindowHandle); // 置于前台 } else { Application.Run(new MainForm()); // 启动新实例 } } }
3、Win32 API 调用
以下是关键的 Win32 API
函数,用于操作窗口显示和前台设置:
[DllImport("User32.dll", EntryPoint = "FindWindow")] public static extern IntPtr FindWindow(string lpClassName, string lpWindowName); [DllImport("user32.dll")] public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow); [DllImport("user32.dll ")] public static extern bool SetForegroundWindow(IntPtr hWnd);
FindWindow
: 根据窗口名称查找窗口句柄。
ShowWindowAsync
: 显示或隐藏窗口。
SetForegroundWindow
: 将窗口设置为前台窗口。
注意事项
1、窗口名称匹配问题
如果窗口标题动态变化,FindWindow
的效果可能不佳,需保证窗口标题唯一或改用其他识别方法。 2、权限问题
如果以管理员权限运行程序,SetForegroundWindow
操作可能会被限制。需要确保权限一致。
3、多线程问题
如果程序使用了多线程,需注意线程间的窗口操作同步。
优化建议
1、使用互斥量
利用 Mutex
可以更简洁地实现程序唯一性。例如:
static Mutex mutex = new Mutex(true, "UniqueAppName", out bool createdNew); if (!createdNew) { // 已经有实例运行 return; }
2、窗口句柄缓存
可以在程序启动时缓存主窗口句柄,避免频繁调用 FindWindow
。
3、日志记录
在实际应用中建议记录重复启动的尝试,以便后续调试和优化。
总结
这是一种基于进程和 Win32 API 的方法来保持程序唯一性的解决方案。代码逻辑清晰,适用于大多数桌面应用场景。如果你有更复杂的需求或更高的性能要求,建议结合互斥量或现代框架特性来实现更可靠的方案。
最后
到此这篇关于防止.NET应用多实例运行的有效方法的文章就介绍到这了,更多相关防止.NET多实例运行内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
asp.net(C#)生成Code39条形码实例 条码枪可以扫描出
这篇文章主要介绍了asp.net(C#)生成Code39条形码实例 条码枪可以扫描出。需要的朋友可以过来参考下,希望对大家有所帮助2014-02-02asp.net下配置数据源时出现: 未将对象引用设置到对象的实例。
未将对象引用设置到对象的实例的一个另类解决方法2008-06-06asp.net Mvc4 使用ajax结合分页插件实现无刷新分页
本篇文章主要介绍了 asp.net Mvc4 使用ajax结合分页插件实现无刷新分页,ajax通过回调函数把控制器返回的分部视图内容加载到主视图中显示,有兴趣的可以了解一下。2017-01-01剖析Asp.Net Web API路由系统---WebHost部署方式
这篇文章主要介绍了剖析Asp.Net Web API路由系统---WebHost部署方式,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。2017-02-02
最新评论