程序单一实例实现 z
不少应用程序有单一实例的需求,也就是同时只能开启一个实例(一般也就是一个进程)。
实现的方式可能有判断进程名字,使用特殊文件等等,但是最靠谱的方式还是使用系统提供的 Mutex 工具。
Mutex是互斥体,命名的互斥体可以跨进程使用,所以可以用以实现程序单一实例这个需求。相关的例子网上应该不少,不过很多给出的例子中并没有注意到一些细节,这里就完整总结下。
命名Permalink
Mutex 需要一个名字,这个名字需要唯一,一般的方式是使用一个固定的 GUID 作为名字。
对于 .NET 应用,可以通过 Assembly 上的GuidAttribute来获取。默认情况下建立工程的时候 VS 就会生成一个 GUID 给 Assembly,这样无需自己再生成一个 GUID 来使用。
另外,为了调试方面,最好给 GUID 加一个便于人识别的前缀,一般就是程序的名字。这样使用一些查看系统对象的工具时,可以方便找到这个 Mutex。
var guidAttr = (GuidAttribute)Attribute.GetCustomAttribute(Assembly.GetExecutingAssembly(), typeof(GuidAttribute)); var key = string.Format("MyApp-}", guidAttr.Value); _mutex = new Mutex(true, key);
判断Permalink
一般在程序启动的代码中进行判断,判断的方式是使用 Mutex 上的WaitOne方法。但是有两点需要注意:
- 程序异常退出,WaitOne 会抛出
AbandonedMutexException
异常,需要处理。 - 如果程序使用了
Application.Restart
来重新启动,就需要 WaitOne 等待更长的时间。这是因为Application.Restart
会在程序退出前启动新程序实例,需要等待原程序完全退出释放 Mutex。
try
{return _mutex.WaitOne(TimeSpan.FromSeconds(1), true); } catch (AbandonedMutexException ex) { if (ex.Mutex != null) ex.Mutex.ReleaseMutex(); return true; }
返回true
则可以正常启动,否则程序已在运行。
释放Permalink
在程序退出时需要释放 Mutex。
_mutex.ReleaseMutex();
通知Permalink
有些场景下,如果应用已在运行,用户再启动应用时,需要将已在运行的应用显示给用户。如果应用已经有自己的进程间通讯方式,那就可以直接利用,如果没有,则可以使用 Windows 系统的消息广播。
P/Invoke 定义:
public const int HWND_BROADCAST = 0xffff; [DllImport("user32")] public static extern bool PostMessage(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam); [DllImport("user32")] public static extern bool SendMessage(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam); [DllImport("user32")] public static extern int RegisterWindowMessage(string message);
程序启动时注册消息:
_showMeMessage = RegisterWindowMessage(key);
判断程序已运行时广播消息:
PostMessage((IntPtr)NativeMethods.HWND_BROADCAST, _showMeMessage, IntPtr.Zero, IntPtr.Zero);
处理消息循环,显示已运行的实例(WinForms 版本):
protected override void WndProc(ref Message m) { if (m.Msg == _showMeMessage) { if (form.WindowState == FormWindowState.Minimized) form.WindowState = FormWindowState.Normal; if (!form.Visible) form.Show(); var top = form.TopMost; form.TopMost = true; form.TopMost = top; } base.WndProc(ref m); }
参考:http://sanity-free.org/143/csharp_dotnet_single_instance_application.html
程序单一实例实现 z相关推荐
- python快递分拣小程序_python英语单词测试小程序代码实例
这篇文章主要简介了python英语单词测试小程序代码实例,文中通过示例代码简介的非常具体,对大家的学习或者工作具有一定的参考学习网上卖,需要的朋友可以学习下 爬取了扇贝英语网,并制作了一个英语单词测试 ...
- python测试代码_python英语单词测试小程序代码实例
这篇文章主要介绍了python英语单词测试小程序代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 爬取了扇贝英语网,并制作了一个英语单词测试的 ...
- python基础代码事例-Python简单基础小程序的实例代码
1 九九乘法表 for i in range(9):#从0循环到8 i += 1#等价于 i = i+1 for j in range(i):#从0循环到i j += 1 print(j,'*',i, ...
- python程序实例教程基础-Python简单基础小程序的实例代码
1 九九乘法表 for i in range(9):#从0循环到8 i += 1#等价于 i = i+1 for j in range(i):#从0循环到i j += 1 print(j,'*',i, ...
- 上海php黑名单,php判断ip黑名单程序代码实例
这篇文章主要介绍了php判断ip黑名单程序代码实例,需要的朋友可以参考下 学校的新闻系统要求有些新闻只开放校内ip浏览,于是重写了一个代码来实现此功能,实现后的结果是,只要把允许访问的ip列入ip.t ...
- 程序运行实例数量的控制
标 题:程序运行实例数量的控制--大全篇[原创] 发信人:bellkwong 经常会碰到有人问如何保证程序只运行一个实例,原来我也零碎的给过两三个方法,今天干脆来个大总结,希望对大家在做程序设计的时候 ...
- java商城项目中多线程执行_java多线程中执行多个程序的实例分析
我们知道多线程因为同时处理子线程的能力,对于程序运行来说,能够达到很高的效率.不过很多人对于多线程的执行方法还没有尝试过,本篇我们将为大家介绍创建线程的方法,在这个基础上,对程序执行多条命令的方法进行 ...
- 商城小程序、实例原型设计、电商app、积分商城、领券中心、会员中心、每日签到、小程序电商、优惠券、移动端电商、Axure原型、rp原型、产品原型、积分、会员卡
商城小程序.实例原型设计.电商app.积分商城.领券中心.会员中心.每日签到.小程序电商.优惠券.移动端电商.Axure原型.rp原型.产品原型.积分.会员卡 Axure演示及下载地址: Untitl ...
- python经典程序实例-Python简单基础小程序的实例代码
1 九九乘法表 for i in range(9):#从0循环到8 i += 1#等价于 i = i+1 for j in range(i):#从0循环到i j += 1 print(j,'*',i, ...
最新文章
- UNICODE 码和字符的相互转换
- ubuntu中pycharm配置opencv2环境
- 计算机操作系统:处理机的调度
- servlet和servlet-mapping的作用------转载于《简书》作者:简单的书写点
- BUG总结—Navicat连接Mysql8.0.11出现1251错误
- 搜索引擎索引之如何建立索引
- 这些工具你利用好了吗?
- ReactNative-地图导航-iOS
- easyui中的datetimebox 只显示年月日_云计算自动化运维之linux-工作中常用命令总结(中)...
- 条码扫描二维码扫描——ZXing android 源码简化
- 用python逆序输出字符串中的所有元素_Python中逆序输出字符串的六种方法
- 区块链100讲:如果连电子钱包都不懂,还谈什么区块链开发(有彩蛋)
- 自动祝福程序(定时发送消息)
- ERR_NAME_NOT_RESOLVED错误的解决方法
- matplotlib绘制雷达图之基本配置——万能模板案例
- win 10 slmgr.vbs -xpr 无法运行,被豆麦笔记打开解决方法
- 独家 | 处理非结构化数据的7个实例(附链接)
- 在缺流量时代,App们需要如何突围
- 关于零售的本质让人不寒而栗
- 股指期货跨期套利策略