单进程运行

转自:http://blogs.microsoft.co.il/blogs/arik/archive/2010/05/28/wpf-single-instance-application.aspx

The Problem

The question this post solves is how to enforce that your WPF application has only one instance?

Solution Source

The solution is based on code found in some WPF reference applications which Microsoft will soon (?) release. I didn’t wrote it, but I used it several times and it’s the best solution I’ve found to date, so I‘d hate to see it unpublished.

Solution Advantages

So, what are the advantages of this solution? after all, it’s not the first time someone posts a solution for this problem.

Well, the most important advantage is that it works. 
No glitches. No special cases. No inherent race conditions. 
It simply works.

Second, it’s easily used. On the next section I’ll show you exactly how to use it.

Third, there’s no constraints on your WPF application. Specifically, your main application / window class doesn’t have to inherit some base class for this to work.

And at last, you don’t need to be dependent on any VB DLL. 
I say this because one of the popular solutions for this problem requires your to add a reference to a (WinForms related!) Visual Basic DLL, which may feel strange for some people.

As a bonus, the solution provides to the first instance the parameters of the second instance when run. This is very useful if you want to integrate you application with the Windows 7 taskbar.

Solution Details

So, let’s see how to make your WPF application having just one instance.

Step 1: Add the file SingleInstance.cs to your project.

Step 2: Add a reference to your project: System.Runtime.Remoting

Step 3: Have your application class implement ISingleInstanceApp (defined in SingleInstance.cs).

The only method in this interface is: 
bool SignalExternalCommandLineArgs(IList<string> args)

This method is called when a second instance of your application tries to run. It has an args parameter which is the same as the command line arguments passed to the second instance.

Step 4: Define your own Main function that uses the single instance class.

Your App class should now be similar to this:

/// <summary>
/// Interaction logic for App.xaml
/// </summary>
publicpartialclassApp

:

Application

,

ISingleInstanceApp

{

privateconststring

Unique =

"My_Unique_Application_String"

;

[STAThread]
public static void Main()
{
if (SingleInstance<App>.InitializeAsFirstInstance(Unique))
{
var application = new App();

application.InitializeComponent();
application.Run();

// Allow single instance code to perform cleanup operations
SingleInstance<App>.Cleanup();
}
}

#region ISingleInstanceApp Members

public bool SignalExternalCommandLineArgs(IList<string> args)
{
// handle command line arguments of second instance
// ...

return true;
}

#endregion
}

Step 5: Set new main entry point

Select Project Properties –> Application and set “Startup object” to your App class name instead of “(Not Set)”.

Step 6: Cancel the default WPF main function

Right-click on App.xaml, Properties, set Build Action to "Page" instead of "Application Definition".

Solution Inner Works

I can summarize it as: Mutex and Remoting, done right. 
If you want to know more details, just have a look at the code.

You can find a WPF sample application here.

That’s it for now, 
Arik Poznanski.

时间: 2024-08-18 13:52:30

单进程运行的相关文章

如何使用Chrome运行参数 个性化你的谷歌浏览器

上一篇文章列出了 Chrome 所有的运行参数,下面介绍一下如何通过这些参数来启动你的浏览器. http://alanland.iteye.com/blog/604025 本文针对第一次使用 Chrome 启动参数(同运行参数)的朋友.原来是截了图的,不过编辑器里的插入图片功能换了几个浏览器都不能用,不知道怎么事,直接的拷贝粘贴也不好使,郁闷~~ (Windows) 一:找到你电脑上 Chrome 的快捷方式.右击选择属性. 二: 选择 [快捷方式] Tab 页. 三:在 [快捷方式] Tab页

报表的数据组织:文件还是数据库?

在报表开发项目中,报表的源数据可以放置在数据库中,也可以放在文件里.比如,一个互联网公司的网站运营报表系统,公司注册用户的基本信息来自于网站系统,使用的是Oracle数据库:用户操作数据来自于网站系统的日志文件,是文本文件.一般的做法是将用户操作数据从文本文件中导入到Oracle中,再用SQL语句去提取和计算数据. 那么,将报表的数据全部放到数据库中是否是最佳做法?可不可以把报表的数据全部或者部分放到文件系统中呢?这两种做法各有什么优缺点呢? 这里我们比较一下,报表工具结合Java程序访问数据文

转: Nodejs概述 by ruanyifeng

目录 简介 安装与更新 版本管理工具nvm 基本用法 REPL环境 异步操作 全局对象和全局变量 模块化结构 概述 核心模块 自定义模块 fs模块 Stream模式 http模块 实例:搭建一个HTTP服务器 处理POST请求 发出请求:request方法 搭建HTTPs服务器 events模块 基本用法 事件类型 EventEmitter对象的其他方法 process模块 属性 方法 事件 cluster模块 配置文件package.json 模块管理器npm npm简介 查看模块信息 模块的

读书笔记-APUE第三版-(7)进程环境

本章关注单进程运行环境:启动&终止.参数传递和内存布局等. 进程启动终止 如图所示: 启动:内核通过exec函数执行程序,在main函数运行之前,会调用启动例程(start-up routine),取得命令行参数和环境变量.可以把启动例程理解为exit(main(argc,argv)). 终止:五种正常终止方式(从main方法返回/exit/_exit/最后一个线程返回/最后一个线程退出):三种异常终止方式(abort/接收到信号/最后一个线程接收到取消请求). exit与_exit关系:exi

CEF3开发者系列之进程和线程

CEF3是一个多进程架构框架,如果有了解过chromium的进程架构的,那么就很容易了解CEF3的多进程了.打开CEF3源代码中发布的cefclient实例,如果打开的页面带有flash或者其他插件.在任务管理其中可以看到四个进程,显示出命令行列.可以看到一个主进程,一般主进程是Browser进程,其他的分别是渲染进程(Render),GPU加速进程(GPU),插件进程(NPAPI或者PPAPI). Browser进程:被定义为主进程,负责窗口管理,界面绘制和网络交互. Render 进程:Bl

Intel MPI 5.1.3安装配置详解

写在之前: MPI简述: MPI的全称是Message Passing Interface即标准消息传递界面,可以用于并行计算.MPI有多种实现版本,如MPICH, CHIMP以及OPENMPI.这里我们采用MPICH版本. MPI是一个库,而不是一门语言.许多人认为,MPI就是一种并行语言,这是不准确的.但是,按照并行语言的分类,可以把FORTRAN+MPI或C+MPI看作是一种在原来串行语言基础之上扩展后得到的,并行语言MPI库可以被FORTRAN77/C/Fortran90/C++调用,从

初识CEF

介绍 CEF全称Chromium Embedded Framework,是一个基于Google Chromium 的开源项目.Google Chromium项目主要是为Google Chrome应用开发的,而CEF的目标则是为第三方应用提供可嵌入浏览器支持.CEF隔离底层Chromium和Blink的复杂代码,并提供一套产品级稳定的API,发布跟踪具体Chromium版本的分支,以及二进制包.CEF的大部分特性都提供了丰富的默认实现,让使用者做尽量少的定制即可满足需求.在本文发布的时候,世界上已

Win7 Chrome的缓存及用户数据位置修改

查阅多处资料后,自己总结并整理了2种方法:使用命令参数.使用mklink命令创建符号链接.建议直接使用第2种方式. 首先找到数据位置并分清楚目录的作用: C:\Users\XXX\AppData\Local\Google\Chrome\UserData    用户数据(这个目录在默认情况下包含了缓存,里面还包括各种配置信息,以及书签.扩展等内容) C:\Users\XXX\AppData\Local\Google\Chrome\UserData\Default\Cache   缓存 方案一: 这

游戏引擎/GUI的设计与实现-常见GUI架构

以X Window为代表的客户/服务器架构. X Window通常是指X服务器及封装了通信协议的客户端库.服务器端主要负责输入事件的分发,窗口层次的管理,以及显示输出的处理,其它功能基本上都是在客户端实现了.我们看到的各种界面元素都是在客户端绘制的,这一部分通常称为ToolKit,应用程序开发者只需要关注ToolKit就行了.以前的ToolKit非常多,经过多年的进化和淘汰,常用的ToolKit主要是GTK+和QT两个了.X Window是非常复杂和晦涩的,以前我花了不少时间去研究用于嵌入式系统