zoukankan      html  css  js  c++  java
  • [转]创建单实例应用程序的三种方法

    背景
    在编写windows桌面应用程序时,如果我们没有特别处理,我们是可以打开多个应用程序实例的。例如,我们在同一台机器上挂打开多个QQ程序,也可以打开多个浏览器窗口。但有些应用程序,却只运行单个实例运行,如Outlook,MSN等。那么如何实现单实例应用程序呢?下面介绍三种方法。

    方法一,扫描进程
    这是最容易想到的方法,实现起来也比较简单。扫描进程的代码如下,假设应用程序名称为MySingleInstance.exe。 www.2cto.com

    Process[] processes = Process.GetProcessesByName("MySingleInstance"); // no ".exe"
    if (processes.Length > 1) {
     MessageBox.Show("Another instance is running.");
     return;
    }
    简单几行代码就可以实现单例应用程序了,只是稍微有些不够友好,因为当试图打开第二个实例时会弹出一个不够友好的对话框“Another instance is running.”,但如果我们把这行代码去掉后,又缺少了用户的交互。因此我们可以安装MSN或OUTLOOK的方式--激活正在运行的实例。

    这需要调用WINDOWS API,如下代码:

    Process[] processes = Process.GetProcessesByName("MySingleInstance");
    if (processes.Length > 1) {
         IntPtr hwnd = processes[0].MainWindowHandle;
         // NOTE: ensure the first intance handle selected
         if (Process.GetCurrentProcess().MainWindowHandle == hwnd) {
             hwnd = processes[1].MainWindowHandle;
         }

         long style = GetWindowLong(hwnd, GWL_STYLE);

         if ((style & WS_MINIMIZE) == WS_MINIMIZE) {
              ShowWindow(hwnd, SW_SHOWNOACTIVATE);
         }
         SetForegroundWindow(hwnd);
         return;
     }
    使用的WINDOWS API的声明,如下:

    [DllImport("user32.dll")]
    private static extern bool ShowWindow(IntPtr hWnd, uint nCmdShow);
    [DllImport("user32.dll")]
    private static extern bool SetForegroundWindow(IntPtr hwnd);
    [DllImport("user32.dll")]
    private static extern long GetWindowLong(IntPtr hwnd, int nIndex);

    private const int SW_SHOWNOACTIVATE = 4;
    const int GWL_STYLE = -16;
    const long WS_MINIMIZE = 0x20000000L;
    完整的代码键附近中Program1.cs
    方法二,互斥量Mutex
    如果你觉得扫描进程比较“笨拙”的话,那么有一个稍微专业一点的做法,使用互斥量Mutex。如果有多线程开发经验的,都应该使用过Mutex,该类比较可以实现线程的同步,而且是可以对其命名,并且是跨进程的。Mutex的构造函数签名:Mutex(bool initiallyOwned, string name, out bool createdNew),其中createdNew表示十分已经存在相同名称的Mutex,如果存在createdNew为false,没有则为true。利用该值可以判断应用程序的实例是否已经被创建。但在createdNew为false的情况时,还是需要方法一,来激活已创建的实例窗口。其实是有Mutex没有减少创建单实例的复杂度,反而更复杂了,而且创建的Mutex对象也不再使用,创建该对象也比较耗资源,该方法一般不会采用。

    方法三,Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase
    当然我们有更加简单,更加专业的方法--使用Microsoft提供的接口--WindowsFormsApplicationBase。Ms提供了Application基类,并且提供了IsSingleInstance的属性,该类位于命名空间Microsoft.VisualBasic.ApplicationServices下,必须添加Microsoft.VisualBasic.dll的引用。我们要做的就是实现该类,并且设置属性IsSingleInstance=True。实现代码:

    internal sealed class MySingleInstanceApplication : WindowsFormsApplicationBase {
        public MySingleInstanceApplication() {
            base.IsSingleInstance = true;
            base.EnableVisualStyles = true;
        }

        protected override void OnCreateMainForm() {
            this.MainForm = new Form1();
        }
    }
    该类的使用,同Application类基本相同,并且看上去更加简洁。
    [STAThread]
    static void Main(string[] args) {
        MySingleInstanceApplication app = new MySingleInstanceApplication();
         app.Run(args);
    }
    运行效果同方法一,二相同,关键是代码更简洁,面向对象。完整代码见Program3.cs

    转文:http://www.2cto.com/kf/201212/173920.html

  • 相关阅读:
    Linux配置防火墙 开启80端口
    微信支付调用JSAPI缺少参数:timeStamp
    php解压zip文件
    css JavaScript 笔记
    css
    html标签
    模拟服务器返回html
    网页特殊符号HTML代码大全
    selectors模块
    select
  • 原文地址:https://www.cnblogs.com/anduinlothar/p/2939040.html
Copyright © 2011-2022 走看看