加入收藏 | 设为首页 | 会员中心 | 我要投稿 安卓应用网 (https://www.0791zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 程序设计 > 正文

.Net平台应用程序单一运行实例代码实现

发布时间:2020-05-23 20:37:00 所属栏目:程序设计 来源:互联网
导读:.Net 平台应用程序单一运行实例代码实现 作者:郑佐 日期:2006-7-2 概述 本文是针对 《基于.Net平台应用程序唯一运行实例实现》的补充,文章给出功能实现代码,其中SingleInstance类实现只允许一个实例运行,Program为测试主程序入口。在代码中标识说明文字

.Net 平台应用程序单一运行实例代码实现 作者:郑佐
日期:2006-7-2 概述 本文是针对 《基于.Net平台应用程序唯一运行实例实现》的补充,文章给出功能实现代码,其中SingleInstance类实现只允许一个实例运行,Program为测试主程序入口。在代码中标识说明文字。完整 代码下载。 主要代码 SingleInstance.cs 文件。 using System; using System.IO; using System.Diagnostics; using System.Threading; using System.Reflection; using System.Runtime.InteropServices; /*------------------------------------------------ Zhengzuo 2006-07-01 http://blog.csdn.net/zhzuo --------------------------------------------------*/ namespace Zhengzuo.CSharpCode { ///<summary> /// 只启动一个应用程序实例控制类 ///</summary> public static class SingleInstance { private const int WS_SHOWNORMAL = 1; [DllImport("User32.dll")] private static extern bool ShowWindowAsync(IntPtr hWnd,int cmdShow); [DllImport("User32.dll")] private static extern bool SetForegroundWindow(IntPtr hWnd); // 标志文件名称 private static string runFlagFullname = null; // 声明同步基元 private static Mutex mutex = null; ///<summary> /// static Constructor ///</summary> static SingleInstance() { } #region api 实现 ///<summary> /// 获取应用程序进程实例,如果没有匹配进程,返回Null ///</summary> ///<returns> 返回当前Process实例 </returns> public static Process GetRunningInstance() { Process currentProcess = Process.GetCurrentProcess();// 获取当前进程 // 获取当前运行程序完全限定名 string currentFileName = currentProcess.MainModule.FileName; // 获取进程名为ProcessName的Process数组。 Process[] processes = Process.GetProcessesByName(currentProcess.ProcessName); // 遍历有相同进程名称正在运行的进程 foreach (Process process in processes) { if (process.MainModule.FileName == currentFileName) { if (process.Id != currentProcess.Id)// 根据进程ID排除当前进程 return process;// 返回已运行的进程实例 } } return null; } ///<summary> /// 获取应用程序句柄,设置应用程序前台运行,并返回bool值 ///</summary> public static bool HandleRunningInstance(Process instance) { // 确保窗口没有被最小化或最大化 ShowWindowAsync(instance.MainWindowHandle,WS_SHOWNORMAL); // 设置真实例程为foreground window return SetForegroundWindow(instance.MainWindowHandle); } ///<summary> /// 获取窗口句柄,设置应用程序前台运行,并返回bool值,重载方法 ///</summary> ///<returns></returns> public static bool HandleRunningInstance() { Process p = GetRunningInstance(); if (p != null) { HandleRunningInstance(p); return true; } return false; } #endregion #region Mutex 实现 ///<summary> /// 创建应用程序进程Mutex ///</summary> ///<returns> 返回创建结果,true表示创建成功,false创建失败。 </returns> public static bool CreateMutex() { return CreateMutex(Assembly.GetEntryAssembly().FullName); } ///<summary> /// 创建应用程序进程Mutex ///</summary> ///<param name="name">Mutex 名称 </param> ///<returns> 返回创建结果,true表示创建成功,false创建失败。 </returns> public static bool CreateMutex(string name) { bool result = false; mutex = new Mutex(true,name,out result); return result; } ///<summary> /// 释放Mutex ///</summary> public static void ReleaseMutex() { if (mutex != null) { mutex.Close(); } } #endregion #region 设置标志实现 ///<summary> /// 初始化程序运行标志,设置成功,返回true,已经设置返回false,设置失败将抛出异常 ///</summary> ///<returns> 返回设置结果 </returns> public static bool InitRunFlag() { if (File.Exists(RunFlag)) { return false; } using (FileStream fs = new FileStream(RunFlag,FileMode.Create)) { } return true; } ///<summary> /// 释放初始化程序运行标志,如果释放失败将抛出异常 ///</summary> public static void DisposeRunFlag() { if (File.Exists(RunFlag)) { File.Delete(RunFlag); } } ///<summary> /// 获取或设置程序运行标志,必须符合Windows文件命名规范 /// 实现生成临时文件为依据,如果修改成设置注册表,那就不需要符合文件命名规范。 ///</summary> public static string RunFlag { get { if(runFlagFullname == null) { string assemblyFullName = Assembly.GetEntryAssembly().FullName; //CommonApplicationData :"C://Documents and Settings//All Users//Application Data" string path = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData); //"C://Program Files//Common Files" //string path = Environment.GetFolderPath(Environment.SpecialFolder.CommonProgramFiles); runFlagFullname = Path.Combine(path,assemblyFullName); } return runFlagFullname; } set { runFlagFullname = value; } } #endregion } } Program.cs 文件。 using System; using System.Windows.Forms; using System.Diagnostics; using Zhengzuo.CSharpCode; namespace Zhengzuo.Test.WinGui { static class Program { [STAThread] static void Main(string[] args) { if (args.Length == 0) // 没有传送参数 { Process p = SingleInstance.GetRunningInstance(); if (p != null) // 已经有应用程序副本执行 { SingleInstance.HandleRunningInstance(p); } else // 启动第一个应用程序 { RunApplication(); } } else // 有多个参数 { switch (args[0].ToLower()) { case "-api": if (SingleInstance.HandleRunningInstance() == false) { RunApplication(); } break; case "-mutex": if (args.Length >= 2) // 参数中传入互斥体名称 { if ( SingleInstance.CreateMutex(args[1]) ) { RunApplication(); SingleInstance.ReleaseMutex(); } else { // 调用HandleRunningInstance()方法显示到前台。 MessageBox.Show(" 程序已经运行!" ); } } else { if (SingleInstance.CreateMutex()) { RunApplication(); SingleInstance.ReleaseMutex(); } else { // 调用HandleRunningInstance()方法显示到前台。 MessageBox.Show(" 程序已经运行!" ); } } break; case "-flag":// 使用该方式需要在程序退出时调用 if (args.Length >= 2) // 参数中传入运行标志文件名称 { SingleInstance.RunFlag = args[1]; } try { if (SingleInstance.InitRunFlag()) { RunApplication(); SingleInstance.DisposeRunFlag(); } else { // 调用HandleRunningInstance()方法显示到前台。 MessageBox.Show(" 程序已经运行!" ); } } catch (Exception ex) { MessageBox.Show(ex.ToString()); } break; default: MessageBox.Show(" 应用程序参数设置失败。" ); break; } } } // 启动应用程序 static void RunApplication() { Application.EnableVisualStyles(); Application.Run(new MainForm()); } } } 功能测试 功能测试类别包括下面五类, 1 .本地系统同一应用程序目录; 2 .本地系统同一应用程序修改运行文件名称使两次运行名称不同; 3 .本地系统两次运行程序目录不同,不修改文件名称; 4 .本地系统不同会话用户登录启动应用程序; 5 .远程计算机程序访问启动应用程序(一个程序在远程另一个在本地)。 运行CMD命令行, 第一种调用方式: WindowsApplication1.exe 或 WindowsApplication1.exe –api 第二种 调用方式: WindowsApplication1.exe –mutex 或WindowsApplication1.exe –mutex {F140AE26-626C-42f8-BD49-45025742205E} 第三种 调用方式: WindowsApplication1.exe –flag 或WindowsApplication1.exe –flag c:/blog.csdn.net.zhzuo 测试结果 备注:O - 表示成功,X – 表示失败,# - 程序第二个运行没有反应 针对远程访问的测试,需要在系统管理工具的.NET Framework 2.0 Configuration中进行设置授权该局域网路径允许访问,否则会抛出System.Security.SecurityException异常。 根据测试结果可见三种实现方式适用范围不同,理想的实现是结合他们的优点进行多点判断。 更多资源 关于.NET平台应用的开发,更多的技术文章可以访问http://blog.csdn.net/zhzuo,对于本文的建议或意见可在网站上留言。

(编辑:安卓应用网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读