WPF两种方法实现单实例应用程序

  所谓单实例应用程序就是只能开启一个进程的应用程序,通常未做处理的WPF程序可以多次点击exe程序,每次点击,系统都会分配一个进程。这样不仅造成了资源的浪费还会导致其他各种问题,例如,我们的程序里面寄宿了一个WCF接口,那多次启动会导致端口绑定错误。为了让大家对此有个更加深刻的印象,下面做个简单的演示。

  1、创建一个简单的WPF应用程序,没做任何处理。如下图所示:

  2、不采用调试模式,打开项目根目录下的bin/Debug,直接点击WPF.SimpleApp.exe运行程序,可以看到程序正常运行,那么现在试试点击多次,然后打开任务管理器,看看。如下图:

  结果就是,我打开了三个WPF.SimpleApp.exe,同时存在三个WPF.SimpleApp.exe进程。

  好了,现在要做的就是做个限制,无论用户点击多少次,始终运行一个exe,同时只能存在一个exe进程。废话不多说,下面进入正题。

  在这之前,因为本人还是比较喜欢winform的启动方式,因此我把创建项目时自动生成的App.xaml删除,新增了个Program.cs文件,代码如下:

using System;
using System.Windows;

namespace WPF.SimpleApp
{
    class Program
    {

        [STAThread]
        static void Main(string[] args)
        {
            
            Application app = new Application();
            MainWindow win = new MainWindow();
            app.Run(win);
           
        }
    }

}

  说明:WPF的启动方式不止这一种,感兴趣的可以自行百度。

  下面进入正题

  1、使用System.Threading.Mutex,Mutex是一个同步基元,也可用于进程间同步。代码如下:

using System;
using System.Windows;

namespace WPF.SimpleApp
{
    class Program
    {
        const string GlobalMutexName = "WPF.SimpleApp.Mutex";

        [STAThread]
        static void Main(string[] args)
        {
            System.Threading.Mutex mutex = null;
            bool isExists = System.Threading.Mutex.TryOpenExisting(GlobalMutexName,out mutex);
            if(isExists && null != mutex)
            {
                //表示互斥体已经存在,即已经打开了一个程序,这里提示用户
                MessageBox.Show("程序已经在运行");
                return;
            }
            else
            {
                //否则创建新的互斥体
                mutex = new System.Threading.Mutex(true, GlobalMutexName);
            }
            Application app = new Application();
            MainWindow win = new MainWindow();
            app.Run(win);
            //程序关闭,记得释放所占用资源
            if (null != mutex)
            {
                mutex.Dispose();
            }
        }
    }
} 

  运行效果:

  

  可以看到,当打开一个应用程序之后,再次点击exe,会提示“程序已经在运行”。关闭程序之后,再次打开(第一次正常,之后提示一样)。

  2、使用Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase包装。

  首先添加对程序集:Microsoft.VisualBasic 的引用,如下图:

  

  然后添加一个SingleWarpInstanceApp类,并继承Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase类,然后重新方法OnStartup和OnStartupNextInstance。
  实现如下:

public class SingleWarpInstanceApp : Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase
    {
        public SingleWarpInstanceApp()
        {
            this.IsSingleInstance = true;
        }

        protected override bool OnStartup(Microsoft.VisualBasic.ApplicationServices.StartupEventArgs eventArgs)
        {
            Application app = new Application();
            MainWindow win = new MainWindow();
            app.Run(win);
            bool tag = base.OnStartup(eventArgs);
            return tag;
        }

        protected override void OnStartupNextInstance(Microsoft.VisualBasic.ApplicationServices.StartupNextInstanceEventArgs eventArgs)
        {
            MessageBox.Show("程序已经在运行");
        }
    }

  在Program启动方法里面加上如下代码:

SingleWarpInstanceApp app = new SingleWarpInstanceApp();
app.Run(args);

  运行效果一样。

  最后贴上Program.cs的代码:

  

using System;
using System.Windows;

namespace WPF.SimpleApp
{
    class Program
    {
        const string GlobalMutexName = "WPF.SimpleApp.Mutex";

        [STAThread]
        static void Main(string[] args)
        {
            #region 第一种方法
            //System.Threading.Mutex mutex = null;
            //bool isExists = System.Threading.Mutex.TryOpenExisting(GlobalMutexName, out mutex);
            //if (isExists && null != mutex)
            //{
            //    //表示互斥体已经存在,即已经打开了一个程序,这里提示用户
            //    MessageBox.Show("程序已经在运行");
            //    return;
            //}
            //else
            //{
            //    //否则创建新的互斥体
            //    mutex = new System.Threading.Mutex(true, GlobalMutexName);
            //}
            //Application app = new Application();
            //MainWindow win = new MainWindow();
            //app.Run(win);
            ////程序关闭,记得释放所占用资源
            //if (null != mutex)
            //{
            //    mutex.Dispose();
            //} 
            #endregion

            #region 第二种方法

            SingleWarpInstanceApp app = new SingleWarpInstanceApp();
            app.Run(args);

            #endregion

        }
    }

    public class SingleWarpInstanceApp : Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase
    {
        public SingleWarpInstanceApp()
        {
            this.IsSingleInstance = true;
        }

        protected override bool OnStartup(Microsoft.VisualBasic.ApplicationServices.StartupEventArgs eventArgs)
        {
            Application app = new Application();
            MainWindow win = new MainWindow();
            app.Run(win);
            bool tag = base.OnStartup(eventArgs);
            return tag;
        }

        protected override void OnStartupNextInstance(Microsoft.VisualBasic.ApplicationServices.StartupNextInstanceEventArgs eventArgs)
        {
            MessageBox.Show("程序已经在运行");
        }
    }
}

 

  至此,完毕。

 

posted @ 2018-10-08 17:40  尋找一個證明  阅读(3142)  评论(0编辑  收藏  举报