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 ...
随机推荐
- 从RTTI谈C++的向下转型
转自:http://blog.chinaunix.net/uid-28541347-id-4251713.html 从RTTI谈C++的向下转型 1.什么是RTTI? RTTI 是“Runtime T ...
- Spring整合Struts2框架的第二种方式(Action由Spring框架来创建)(推荐大家来使用的)
1. spring整合struts的基本操作见我的博文:https://www.cnblogs.com/wyhluckdog/p/10140588.html,这里面将spring与struts2框架整 ...
- 安全运维 -- Linux服务器使用公私钥密匙证书登录
环境:Ubuntu 16 前言 黑客遍地都是,ssh/pop3/ftp等爆破工具的流行让站长的日常运维工作量大大加重.Metasplot,Bruter等工具更是针对以上协议有专门 的破解方法,有字典破 ...
- linux中的hosts文件
1.主机名: 无论在局域网还是INTERNET上,每台主机都有一个IP地址,是为了区分此台主机和彼台主机,也就是说IP地址就是主机的门牌号. 公网:IP地址不方便记忆,所以又有了域名.域名只是在公网( ...
- Judy Array - Example
“ In computer science and software engineering, a Judy array is a data structure that has high perfo ...
- springmvc 测试项目示例
新建一个 maven项目 pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi=" ...
- bat批量重命名文件
@echo off setlocal enabledelayedexpansion set prefix="mai" set /a num=000 rem 排序/o:? -代表逆序 ...
- 2018.08.27 rollcall(非旋treap)
描述 初始有一个空集,依次插入N个数Ai.有M次询问Bj,表示询问第Bj个数加入集合后的排名为j的数是多少 输入 第一行是两个整数N,M 接下来一行有N个整数,Ai 接下来一行有M个整数Bj,保证数据 ...
- 如何更改myecelipse、eclipse的Project Explorer的背景颜色
这个是我研究了很久发现的,因为myecelipse.eclipse本身是随着系统的颜色改变而改变的,windows系统都会随着系统改变而改变的,所以找了很多资料都没能改变它的背景色,今天发现了一个不错 ...
- web.xml 404 500 配置
web.xml <error-page> <error-code>404</error-code> <location>/error404.html&l ...