WPF:如何实现单实例的应用程序(Single Instance)

原文:WPF:如何实现单实例的应用程序(Single Instance)

好吧,这是我将WPF与Windows Forms进行比较的系列文章的第四篇,讨论一下如何实现单实例(single instance)

先来看第一种最简单粗暴的做法:

检测进程名,如果名称一样,则表示程序已经启动了,就不再启动.

    protected override void OnStartup(StartupEventArgs e)
    {
        // Get Reference to the current Process
        Process thisProc = Process.GetCurrentProcess();
        // Check how many total processes have the same name as the current one
        if (Process.GetProcessesByName(thisProc.ProcessName).Length > 1)
        {
            // If ther is more than one, than it is already running.
            MessageBox.Show("Application is already running.");
            Application.Current.Shutdown();
            return;
        }

        base.OnStartup(e);
    }
很简单,不是吗?但简单有什么错呢? 它很实用.
[注意]这个代码如果在visual studio中调试则无效,因为visual studio调试用的进程是加了一个vshost的后缀的。
?
第二种方案我觉得应该还是可以用mutex来实现嘛,看看下面的代码
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Windows;
using System.Diagnostics;
using System.Threading;

namespace WpfApplication1
{
    ///


    /// App.xaml 的交互逻辑
    ///
    public partial class App : Application
    {
        protected override void OnStartup(StartupEventArgs e)
        {
            bool createNew;
            Mutex mutex = new Mutex(true, "MyApplication", out createNew);
            if (createNew)
                base.OnStartup(e);
            else
            {
                MessageBox.Show("程序已经启动了");
                Application.Current.Shutdown();
            }
        }

    }
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

这一种做法的结果与第一种很类似,或者说没有任何区别。

?

看起来解决问题了,但仍然不是很理想的。最好的情况是,当用户开启第二个实例的时候,如果第一个实例没有处于活动状态,则应该激活它。

我们很自然还是联想到了原先在Windows Forms时代的WindowsFormsApplicationBase,那里面做这个事情太简单了。

首先,添加Microsoft.VisualBasic的引用

namespace WpfApplication1
{
    public class EntryPoint
    {
        [STAThread]
        public static void Main(string[] args)
        {
            SingleInstanceManager manager = new SingleInstanceManager();
            manager.Run(args);
        }
    }

    // Using VB bits to detect single instances and process accordingly:
    //  * OnStartup is fired when the first instance loads
    //  * OnStartupNextInstance is fired when the application is re-run again
    //    NOTE: it is redirected to this instance thanks to IsSingleInstance
    public class SingleInstanceManager : WindowsFormsApplicationBase
    {
        SingleInstanceApplication app;

        public SingleInstanceManager()
        {
            this.IsSingleInstance = true;
        }

        protected override bool OnStartup(Microsoft.VisualBasic.ApplicationServices.StartupEventArgs e)
        {
            // First time app is launched
            app = new SingleInstanceApplication();
            app.Run();
            return false;
        }

        protected override void OnStartupNextInstance(StartupNextInstanceEventArgs eventArgs)
        {
            // Subsequent launches
            base.OnStartupNextInstance(eventArgs);
            app.Activate();
        }
    }

    public class SingleInstanceApplication : Application
    {
        protected override void OnStartup(System.Windows.StartupEventArgs e)
        {
            base.OnStartup(e);

            // Create and show the application‘s main window
            //MainWindow window = new MainWindow();
            Window1 window = new Window1();
            window.Show();
        }

        public void Activate()
        {
            // Reactivate application‘s main window
            this.MainWindow.Show();
            this.MainWindow.Activate();
        }
    }
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

时间: 2024-08-28 06:46:05

WPF:如何实现单实例的应用程序(Single Instance)的相关文章

使用 WPF 创建单实例应用程序

一个简单的例子就是大家在使用很多应用程序,例如在使用Microsoft Word 时会遇到一种情况,不管你打开多少个文档,系统一次只能加载一个winword.exe 实例.当打开新文档时,文档在新窗口显示,但是始终只有一个应用程序控制所有文档窗口:如:可以提供平铺当前所有文档中相邻窗口的文档的特性. 对于创建单实例的应用程序,WPF本身没有提供自带的解决方法,但可以通过变通的方式来实现——思路是当触发ApplicationStartup事件时,检查另一个实例是否在运行.方法是通过使用全局的mut

单实例应用程序

一.概念:一个程序在系统中只能启动一个实例,这样的程序称为单实例应用程序.例如Windows下的任务管理器.回收站.播放器.文件系统等等. 二.实现思想与方法: (1)核心思想:在当前系统中,只需要有能表示程序是否启动的标志,那么就可以利用它来实现单实例应用程序. (2)具体步骤:每当程序启动的时候,都需要先检测这个启动标志,当标志指示已经有实例存在,则当前程序退出,否则运行业务. (3)实现单实例应用程序的方法:共享内存.绑定端口.命名管道.文件锁等等. 三.实现案例:运用文件锁实现 代码转载

c#设计应用程序单实例运行

利用WindowsFormsApplicationBase的IsSingleInstance来控制应用程序只能单实例运行. [DllImport("user32.dll", EntryPoint = "ShowWindow", CharSet = CharSet.Auto)] public static extern int ShowWindow(IntPtr hwnd, int nCmdShow); [DllImport("User32.dll"

Winform and WPF 第二遍双击快捷方式或应用程序打开原来的应用程序而不新建一个实例[进程通信 1]

private void Window_Loaded(object sender, RoutedEventArgs e)         {             Process[] pro = Process.GetProcesses();             int n = pro.Where(p => p.ProcessName.Equals("进程名称")).Count();             if (n > 1)             {      

C++实现程序单实例运行的两种方式

简介 在我们编写程序的时候,经常会注意到的一个问题就是如何能够让程序只运行一个实例,确保不会让同一个程序多次运行,从而产生诸多相同进程,给我们的带来不便呢?那么常用的有以下四种方法,第一种方法是通过扫描进程列表比对进程名来检测,第二种方法是通过枚举程序窗口的方式,第三种方法是采用共享全局变量来实现,第四种方法是通过创建互斥体来实现. 那么在这些方法中,第一种和第二种方法是有缺陷的,扫描进程列表比对进程名容易对相同进程名字的不同程序产生误报,枚举窗口不适用于无窗口程序且与扫描进程列表的方法也有相同

Spring单实例、多线程安全、事务解析

原文:http://blog.csdn.net/c289054531/article/details/9196053 引言: 在使用Spring时,很多人可能对Spring中为什么DAO和Service对象采用单实例方式很迷惑,这些读者是这么认为的: DAO对象必须包含一个数据库的连接Connection,而这个Connection不是线程安全的,所以每个DAO都要包含一个不同的Connection对象实例,这样一来DAO对象就不能是单实例的了. 上述观点对了一半.对的是“每个DAO都要包含一个

【单实例】php

从以上代码中,我们总结出PHP单例模式实现的核心要点有如下三条:1.需要一个保存类的唯一实例的静态成员变量(通常为$_instance私有变量)2.构造函数和克隆函数必须声明为私有的,这是为了防止外部程序new类从而失去单例模式的意义3.必须提供一个访问这个实例的公共的静态方法(通常为getInstance方法),从而返回唯一实例的一个引用PHP单例模式的缺点众所周知,PHP语言是一种解释型的脚本语言,这种运行机制使得每个PHP页面被解释执行后,所有的相关资源都会被回收.也就是说,PHP在语言级

关于struts和Spring 结合到一起之后存在ACtion创建单实例还是多

转自(http://www.cnblogs.com/zyzcj/p/5652128.html) struts 2的Action是多实例的并非单例,也就是每次请求产生一个Action的对象.原因是:struts 2的Action中包含数据,例如你在页面填写的数据就会包含在Action的成员变量里面.如果Action是单实例的话,这些数据在多线程的环境下就会相互影响,例如造成别人填写的数据被你看到了.所以Struts2的Action是多例模式的. 问题出现了,可以让struts2的action变成单

对Servlet单实例多线程的理解。

0 Servlet如何处理多个请求访问? Servlet容器默认是采用单实例多线程的方式处理多个请求的: Servlet是单实例多线程运行方式,所以对象变量线程不安全,局部变量线程安全的. 1.当web服务器启动的时候(或客户端发送请求到服务器时),Servlet就被加载并实例化(只存在一个Servlet实例): 2.容器初始化化Servlet主要就是读取配置文件(例如tomcat,可以通过servlet.xml的<Connector>设置线程池中线程数目,初始化线程池通过web.xml,初始