WPF点滴(2) 创建单实例应用程序
最近有同事问道在应用程序启动之后,再次双击应用程序,如何保证不再启动新的应用程序,而是弹出之前已经启动的进程,本质上这就是创建一个单实例的WPF应用程序。在VS的工程树中有一个App.xaml和App.xaml.cs(这两个文件都是VS自动生成的),在App.xaml.cs中定义了App类,该类继承自System.Windows.Application,从类的命名上也很容易看出这些类是跟应用程序的管理相关的,在讲创建单实例应用程序之前,我们先了解一下Application这个类。
在上一篇WPF点滴(1) Main 函数中有部分对Application类的介绍,Application类封装了WPF应用程序,并管理其生命周期,以下代码用来创建一个Application:
Application app = new Application();
TestWindow window = new TestWindow();
app.MainWindow = window;
window.Show();
app.Run();
上面的代码创建了一个Application,并将该Application的主窗口设置为TestWindow,可以将以上代码简化为同样作用的以下代码:
Application app = new Application();
TestWindow window = new TestWindow();
app.Run(window);
需要注意的是VS自动生成的App类中使用了另一种方法来初始化Application和主窗口,通过资源路径来设置主窗口,
Application app = new Application();
app.StartupUri = new Uri("TestWindow.xaml", UriKind.Relative);
app.Run();
以上介绍了如何通过代码启动一个WPF应用程序,下面介绍以下Application类的几个常用场景:
1. 应用程序启动后的初始化和退出前的清理,这里会用到Startup和Exit这两个事件,或者重载OnStartup和OnExit,这两种方法是等效的,分别在程序启动和退出时触发;
2. 捕获应用程序未处理的异常,DispatcherUnhandledException,异常处理的原则是就近捕获,就近处理,这个事件更多是为了处理意料外的异常,防止程序奔溃的最后一层保护,因此不推荐过分依赖于这个事件中的异常处理。另外需要注意的是这个事件只会捕获主线程(UI线程)中的异常,后台线程中的未处理异常不会触发该事件;
3. 在后台线程中访问UI,Application.Current.Dispatcher.Invoke(),这种方法比较简单,另外一种方式是通过SynchronizationContext,这种方式更灵活一些。
现在终于可以切入正题了,如何创建创建单实例应用程序,前面说到了Startup这个事件,比较直接的方法是Startup的事件处理函数里判断是否已经存在了另外一个已经启动的应用程序,如果是就结束当前程序。这种方法可以实现单实例应用程序的效果,但是太暴力了,而且严格意义上并不是完全的单实例,应用程序毕竟已经启动了,虽然又被干掉了。
下面介绍的是WPF的推荐方式,使用Windows窗体提供的内置支持,借助WindowsFormsApplicationBase类,指定应用程序为单实例模式“IsSingleInstance = true”,
public class SingleInstanceApplication : WindowsFormsApplicationBase
{
private App m_App;
public SingleInstanceApplication()
{
IsSingleInstance = true;
}
protected override bool OnStartup(StartupEventArgs eventArgs)
{
m_App = new App
{
StartupUri = new System.Uri("MainWindow.xaml", System.UriKind.Relative)
};
m_App.Run();
return false;
}
protected override void OnStartupNextInstance(StartupNextInstanceEventArgs eventArgs)
{
base.OnStartupNextInstance(eventArgs);
}
}
重写Main函数(具体方法参见WPF点滴(1) Main 函数),可以看到SingleInstanceApplication充当了App的wrapper,通过SingleInstanceApplication来启动应用程序,并做单实例的的控制,SingleInstanceApplication.OnStartup()在应用程序首次启动时触发,SingleInstanceApplication.OnStartupNextInstance()在应用程序已经启动并尝试再次启动时触发。做这样的设计是为了实现类似Word这样的效果,Word只存在一个运行中的应用程序,每次双击并没有启动新的Word程序,只是打开了一个新窗口而已,而文档的路径就是通过“StartupEventArgs eventArgs”和“StartupNextInstanceEventArgs eventArgs”这两个命令行参数来传递的。
public class StartUp
{
[STAThread]
public static void Main(string[] args)
{
SingleInstanceApplication application = new SingleInstanceApplication();
application.Run(args);
}
}
WPF没有原生支持单实例模式,以上方法实际上是来自VB的一个设计特性,WindowsFormsApplicationBase的命名空间是Microsoft.VisualBasic.ApplicationServices,使用这个类需要添加对Microsoft.VisualBasic.dll的引用。
WPF点滴(2) 创建单实例应用程序的更多相关文章
- 使用 WPF 创建单实例应用程序
一个简单的例子就是大家在使用很多应用程序,例如在使用Microsoft Word 时会遇到一种情况,不管你打开多少个文档,系统一次只能加载一个winword.exe 实例.当打开新文档时,文档在新窗口 ...
- WPF使用Mutex创建单实例程序失效
vs2019 1.引入名称空间 using System.Threading; using System.Runtime.InteropServices; 2.导入dll并声明方法 [DllImpor ...
- WPF学习笔记 - 如何用WPF创建单实例应用程序
使用一个已命名的(操作系统范围的)互斥量. bool mutexIsNew; using(System.Threading.Mutex m = new System.Threading.Mulex(t ...
- WPF 单实例应用程序
例如:Microsoft Word,不管打开多少个文档(也不管它们是如何打开的),一次只能加载 winword.exe 一个实例. 这便是单实例应用程序. 对于这种单实例应用程序,WPF 本身并未提供 ...
- WPF:如何实现单实例的应用程序(Single Instance)
原文:WPF:如何实现单实例的应用程序(Single Instance) 好吧,这是我将WPF与Windows Forms进行比较的系列文章的第四篇,讨论一下如何实现单实例(single instan ...
- Oracle - 给rac创建单实例dg,并做主从切换
一.概述 本文将介绍如何给rac搭建单节点的dg,以及如何对其进行角色转换.预先具备的知识(rac搭建,单实例-单实例dg搭建) 二.实验环境介绍 主库rac(已安装rac,并已有数据库orcl)ra ...
- 关于struts和Spring 结合到一起之后存在ACtion创建单实例还是多
struts 2的Action是多实例的并非单例,也就是每次请求产生一个Action的对象.原因是:struts 2的Action中包含数据,例如你在页面填写的数据就会包含在Action的成员变量里面 ...
- C# 实现单实例程序
在我们经常使用的软件中,当我们已经打开后,再次打开时,有的软件不会出现两个.例如有道词典,会将上次的界面显示出来,或者提示我们“该程序已经运行...”.我通过一个简单的C# WPF例子来说明. 首先我 ...
- DevExpress Winform使用单例运行程序方法和非DevExpress使用Mutex实现程序单实例运行且运行则激活窗体的方法
原文:DevExpress Winform使用单例运行程序方法和非DevExpress使用Mutex实现程序单实例运行且运行则激活窗体的方法 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA ...
随机推荐
- VMware安装Windows注意
安装Windows通用步骤,分区,重建分区表,重写MBR引导.安装即可. VMware安装Windows 如果进不了CM/ROM,在.vmx文件里: 加入一行:bios.forceSetupOnce ...
- TZOJ 4865 统计单词数(模拟字符串)
描述 一般的文本编辑器都有查找单词的功能,该功能可以快速定位特定单词在文章中的位置,有的还能统计出特定单词在文章中出现的次数. 现在,请你编程实现这一功能,具体要求是:给定一个单词,请你输出它在给定的 ...
- tortoise svn 请求的名称有效,但是找不到请求的类型的数据
可能是博客园出bug了,现在无法放图,间断重复刷新十多次依然如故,弃之 这个问题是在安装完svn服务器(visual svn)后复制url,tortoise svn import 粘贴url后 出现的 ...
- DNA motif 搜索算法总结
DNA motif 搜索算法总结 2011-09-15 ~ ADMIN 翻译自:A survey of DNA motif finding algorithms, Modan K Das et. al ...
- 80% UI 初学者走过的弯路,你走了几条?
关于UI 对于初学UI设计的人而言,可能对UI具体是做什么,或者自己是否能顺利转行胜任这样的岗位存在一定的顾虑,今天我们就来重点说说UI是做什么的,以及学UI到有哪些需要避免的弯路. 1.UI设计是做 ...
- 彻底关闭win10的自动更新,一定要坚持看到最后一页
https://jingyan.baidu.com/article/9faa7231e7b78b473c28cbb6.html 是否好使我还在测试,不好使的话,再跟新 2018-05-20 今天电脑又 ...
- spring 3 mvc 的 @ResponseBody返回数据中文乱码
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter&q ...
- sql中 in 、not in 、exists、not exists 用法和差别
% 的一类. NOTIN:通过 NOTIN 关键字引入的子查询也返回一列零值或更多值. 以下查询查找没有出版过商业书籍的出版商的名称. SELECT pub_name FROM publishers ...
- sql server 2008安装的时候选NT AUTHORITY\NEWORK SERVICE 还是选 NT AUTHORITY\SYSTEM ?
sql server 2008安装的时候选NT AUTHORITY\NEWORK SERVICE 还是选 NT AUTHORITY\SYSTEM ? sql server 2008安装的时候选NT A ...
- hdu-2844(完全背包+二进制优化模板)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2844 思路:问1-m能的得到的硬币的值,所以dp[i]==i即可. #include<iostr ...