C#开发单实例应用程序并响应后续进程启动参数

C#默认的WinForm模板是不支持设置单实例的,也没有隔壁大哥VB.NET那样有个“生成单个实例应用程序”的勾选选项(VB某些时候要比C#更方便),实现单实例可以有多种方法:

  • 检测同名进程:Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName),如果集合的Length > 1那就表明已有同名进程了,如果有需要还可以进一步检查该进程的路径;
  • 命名互斥锁:Mutex,网上介绍的很多都是这种方法;
  • 锁定文件:使用File.Create方法创建文件并在程序退出时释放,如果创建失败则表明已经有实例在运行;
  • VB.NET方法:WindowsFormsApplicationBase,个人认为该方法最完美,可以接收后续进程的启动参数,还可以弹出前序进程的主窗体。

WindowsFormsApplicationBase是一个Microsoft.VisualBasic.ApplicationServices命名空间下的类,是微软为VB.NET实现应用程序启动控制的类,其内部是以命名管道通信来实现的。既然是同一个爹的东西,C#拿过来用毫无违和感。Microsoft.VisualBasic和Microsoft.CSharp一样,都是.NET Framework中的一部分,不用担心会缺少运行环境。

WindowsFormsApplicationBase类的一些常用属性和方法:

  • 属性IsSingleInstance:设置当前进程是否为单实例进程,在构造方法中设置,如果是后续进程且为值true,构造方法结束后会给前序进程发送启动参数,然后就退出进程了,不会执行到下面的OnStartup;
  • 方法OnStartup:首次启动后运行,返回false就会退出进程,后续进程永远不会运行到该方法;
  • 方法OnStartupNextInstance:后续进程启动后的重写方法,前序进程会接收到后续进程的启动参数,弹出主窗体等;
  • 方法OnCreateMainForm:创建主窗体的重写方法,必须指定主窗体。

创建一个单实例应用程序并响应后续进程参数的大概过程:

  • 创建一个项目名称为“SingleInstanceSample”的Windows窗体项目;
  • 添加引用“Microsoft.VisualBasic”;
  • 重命名“Form1”为“MainForm”;
  • 添加类“ApplicationBase.cs”,继承自“WindowsFormsApplicationBase”;
  • 修改“Program.cs”,从“ApplicationBase”启动。

各个类的代码如下:

  • Program.cs 
 1 using System;  2 using System.Windows.Forms;  3   4 namespace SingleInstanceSample  5 {  6     internal static class Program  7     {  8         [STAThread]  9         static void Main(string[] args) 10         { 11             Application.EnableVisualStyles(); 12             Application.SetCompatibleTextRenderingDefault(false); 13  14             var app = new ApplicationBase(); 15             app.Run(args); 16         } 17     } 18 }

  • ApplicationBase.cs
 1 using Microsoft.VisualBasic.ApplicationServices;  2 using System.IO;  3   4 namespace SingleInstanceSample  5 {  6     internal class ApplicationBase : WindowsFormsApplicationBase  7     {  8         public ApplicationBase() : base(AuthenticationMode.Windows)  9         { 10             //指示进程为单进程:IsSingleInstance 11             base.IsSingleInstance = true; 12             base.SaveMySettingsOnExit = true; 13             base.ShutdownStyle = ShutdownMode.AfterMainFormCloses; 14         } 15  16         /// <summary> 17         /// 首次启动后的重写方法,返回false就会退出进程, 18         /// 比如可以显示登录窗体,登录失败返回false就不会运行到OnCreateMainForm 19         /// </summary> 20         protected override bool OnStartup(StartupEventArgs eventArgs) 21         { 22              base.OnStartup(eventArgs); 23  24             //处理当前进程的启动参数 25  26             return true; 27         } 28  29         /// <summary> 30         /// 后续进程启动后的重写方法 31         /// </summary> 32         protected override void OnStartupNextInstance(StartupNextInstanceEventArgs eventArgs) 33         { 34             base.OnStartupNextInstance(eventArgs); 35  36             //处理后续进程的启动参数 37         } 38  39         /// <summary> 40         /// 指定主窗体, 41         /// 除非OnStartup返回false,否则必须指定主窗体 42         /// </summary> 43         protected override void OnCreateMainForm() 44         { 45             base.MainForm = new MainForm(); 46         } 47     } 48 }

发表评论

评论已关闭。

相关文章