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("程序已經在運行");
        }
    }
}

 

  至此,完畢。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM