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 }

C#开发单实例应用程序并响应后续进程启动参数的更多相关文章

  1. EasyDSS高性能流媒体服务器前端重构(五)- webpack + vue-router 开发单页面前端实现按需加载 - 副本

    为了让页面更快完成加载, 第一时间呈现给客户端, 也为了帮助客户端节省流量资源, 我们可以开启 vue-router 提供的按需加载功能, 让客户端打开页面时, 只自动加载必要的资源文件, 当客户端操 ...

  2. EasyDSS高性能RTMP、HLS(m3u8)、HTTP-FLV、RTSP流媒体服务器前端重构(五)- webpack + vue-router 开发单页面前端实现按需加载

    为了让页面更快完成加载, 第一时间呈现给客户端, 也为了帮助客户端节省流量资源, 我们可以开启 vue-router 提供的按需加载功能, 让客户端打开页面时, 只自动加载必要的资源文件, 当客户端操 ...

  3. 你们信不信一句Console.WriteLine就能让你的控制台程序失去响应

    好久没更新博客了,今天是扒衣见君节,难得闲下来就来说说一个最近有趣的发现吧. 首先废话不多说,直接上代码吧 class Program { static void Main(string[] args ...

  4. Android开发之ViewPager+ActionBar+Fragment实现响应式可滑动Tab

     今天我们要实现的这个效果呢,在Android的应用中十分地常见,我们可以看到下面两张图,无论是系统内置的联系人应用,还是AnyView的阅读器应用,我们总能找到这样的影子,当我们滑动屏幕时,Tab可 ...

  5. EJB_开发单表映射的实体bean

    开发单表映射的实体bean 实体bean 它属于java持久化规范(JPA)里的技术,实体bean通过元数据在Javabean和数据库表之间建立起映射关系,然后Java程序员就可以随心所欲的使用面向对 ...

  6. Laravel 5.5 + Vue 开发单页应用

    上次我用 laravel5.3 + Vue 开发了一个简单的单页应用,这次我打算将其升级到 laravel5.5,在升级的过程中,做一下记录,其源码放在 github 上面,源码地址   开发环境 软 ...

  7. 「微信小程序」PHP异步进程async-helper实例详解

    PHP异步进程async-helper实例详解 PHP 的异步进程助手,借助于 AMQP 实现异步执行 PHP 的方法,将一些很耗时.追求高可用.需要重试机制的操作放到异步进程中去执行,将你的 HTT ...

  8. Mybatis高级:Mybatis注解开发单表操作,Mybatis注解开发多表操作,构建sql语句,综合案例学生管理系统使用接口注解方式优化

    知识点梳理 课堂讲义 一.Mybatis注解开发单表操作 *** 1.1 MyBatis的常用注解 之前我们在Mapper映射文件中编写的sql语句已经各种配置,其实是比较麻烦的 而这几年来注解开发越 ...

  9. angular开发单页面应用--页面资源部分

    关于angular是什么,能够干什么就不在这里解释了,自行搜索了,或者等稍晚一点再解释... angular适合开发单页面应用,这句话在介绍angular的网站和博客里都可以提到.因为angular是 ...

  10. 使用ProcDump在程序没有响应时自动收集dump

    博客搬到了fresky.github.io - Dawei XU,请各位看官挪步.最新的一篇是:使用ProcDump在程序没有响应时自动收集dump.

随机推荐

  1. csapp-bomblab(自信满满版)

    反汇编bomb文件 要查看机器代码文件的内容,有一类称为反汇编器(disassembler,assembler是汇编程序,dis-加在某些词语前表示相反的意思)的程序非常有用.这些程序根据机器代码产生 ...

  2. Oracle中ALTER TABLE的五种用法(四、五)

    首发微信公众号:SQL数据库运维 原文链接:https://mp.weixin.qq.com/s?__biz=MzI1NTQyNzg3MQ==&mid=2247485212&idx=1 ...

  3. 【题解】[NOIP2001 普及组] 装箱问题

    [NOIP2001 普及组] 装箱问题 这是一道动态规划题. 那就先定义状态吧(这里用的是一维滚动数组). \(f[j]\) 代表当我有 \(j\) 这么多容量可以用时,能装的最大重量是多少. 好,状 ...

  4. pageoffice在线打开word文件加盖电子印章

    一.加盖印章的 js 方法 js方法 二.常见使用场景 1.常规盖章.弹出用户名.密码输入框,选择对应印章. 点击盖章按钮弹出用户名密码登录框,登录以后显示选择电子印章. document.getEl ...

  5. flask-wtf和WTForms官网翻译详解

    https://flask-wtf.readthedocs.io/en/stable/# https://wtforms.readthedocs.io/en/2.3.x/ 介绍: wtformflas ...

  6. 安卓开发封装处理Retrofit协程请求中的异常

    上篇文章讲解了怎么使用Kotlin的协程配合Retrofit发起网络请求,使用也是非常方便,但是在处理请求异常还不是很人性化.这篇文章,我们将处理异常的代码进行封装,以便对异常情况返回给页面,提供更加 ...

  7. Specs satisfying the `flutter_twitter (from `.symlinks/plugins/flutter_twitter/ios`)` dependency were found, but they required a higher minimum deployment target

    MXFlutter的依赖发生变化,需要将iOS最低系统版本提高 修改之后,进入到MXFlutter目录,执行 flutter run 发现编译错误 咨询了下,mxflutter需要flutter为 用 ...

  8. Android桌面Launcher源码浅析

    在Android启动过程-万字长文(Android14)中介绍了Android系统的启动过程,本篇文章将继续介绍桌面应用Launcher. 一.Launcher介绍 在Android启动过程-万字长文 ...

  9. REACT 前端界面提交

    在react项目中安装代理中间件 setupProxy.js文件 const { createProxyMiddleware: proxy } = require('http-proxy-middle ...

  10. kettle从入门到精通 第二十六课 再谈 kettle Transformation executor

    1.前面文章有学习过Transformation executor ,但后来测试kettle性能的时候遇到了很大的问题,此步骤的处理性能太慢,导致内存溢出等问题.所以再次一起学习下此步骤的用法. 2. ...