欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C# 禁止应用程序多次启动的实例

程序员文章站 2024-02-18 12:31:46
通常我们的情况是,双击一个exe文件,就运行一个程序的实体,再双击一次这个exe文件,又运行这个应用程序的另一个实体。就拿qq游戏来说吧,一台电脑上一般只能运行一个qq游戏...

通常我们的情况是,双击一个exe文件,就运行一个程序的实体,再双击一次这个exe文件,又运行这个应用程序的另一个实体。就拿qq游戏来说吧,一台电脑上一般只能运行一个qq游戏大厅(不过以前听说过有双开的外挂)。

那我们的程序也能像qq游戏那里禁止多次启动吗,答案是可以的,下面介绍下一个简单的实现方法,那就是mutex(互斥)。

      mutex(mutual exclusion,互斥)是.net framework中提供跨多个线程同步访问的一个类。它非常类似了monitor类,因为他们都只有一个线程能拥有锁定。而操作系统能够识别有名称的互斥,我们可以给互斥一个唯一的名称,在程序启动之前加一个这样的互斥。这样每次程序启动之前,都会检查这个命名的互斥是否存在。如果存在,应用程序就退出。

复制代码 代码如下:

static class program
    {
        /// <summary>
        /// the main entry point for the application.
        /// </summary>
        [stathread]
        static void main()
        {
            bool creatednew;
            //系统能够识别有名称的互斥,因此可以使用它禁止应用程序启动两次
            //第二个参数可以设置为产品的名称:application.productname

            //每次启动应用程序,都会验证名称为singletonwinappmutex的互斥是否存在
            mutex mutex = new mutex(false, "singletonwinappmutex", out creatednew);

            //如果已运行,则在前端显示
            //creatednew == false,说明程序已运行
            if (!creatednew)
            {
                process instance = getexistprocess();
                if (instance != null)
                {
                    setforegroud(instance);
                    application.exit();
                    return;
                }
            }
            application.enablevisualstyles();
            application.setcompatibletextrenderingdefault(false);
            application.run(new mainform());
        }

        /// <summary>
        /// 查看程序是否已经运行
        /// </summary>
        /// <returns></returns>
        private static process getexistprocess()
        {
            process currentprocess = process.getcurrentprocess();
            foreach (process process in process.getprocessesbyname(currentprocess.processname))
            {
                if ((process.id != currentprocess.id) &&
                    (assembly.getexecutingassembly().location == currentprocess.mainmodule.filename))
                {
                    return process;
                }
            }
            return null;
        }

        /// <summary>
        /// 使程序前端显示
        /// </summary>
        /// <param name="instance"></param>
        private static void setforegroud(process instance)
        {
            intptr mainformhandle = instance.mainwindowhandle;
            if (mainformhandle != intptr.zero)
            {
                showwindowasync(mainformhandle, 1);
                setforegroundwindow(mainformhandle);
            }
        }

        [dllimport("user32.dll")]
        private static extern bool setforegroundwindow(intptr hwnd);

        [dllimport("user32.dll")]
        private static extern bool showwindowasync(intptr hwnd, int cmdshow);
    }