zoukankan      html  css  js  c++  java
  • C# 实现单实例程序

    在我们经常使用的软件中,当我们已经打开后,再次打开时,有的软件不会出现两个。例如有道词典,会将上次的界面显示出来,或者提示我们“该程序已经运行...”。我通过一个简单的C# WPF例子来说明。

    首先我们要了解一下线程中的互斥体(Mutex),引用MSDN官方文档解释,这是一个同步基元,可以用于进程间同步。请参考下面的代码:

        public App()
        {
            bool isNewInstance;
            string appName = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
            Mutex mtx = new Mutex(true, appName, out isNewInstance);
    
            if (!isNewInstance)
            {
                MessageBox.Show("The app is running now.");
                Application.Current.Shutdown();
            }
        }

    这样就可以实现一个单实例程序。当该程序已经运行一次之后,再运行时会提示我们“The app is running now.”.

    另一种情况是再运行该程序时,直接把刚才的程序显示出来(可能此时程序已经最小化到任务栏)。 实现思路:先找到当前的Process,然后调用ShowWindow方法,把隐藏或者最小化的窗体进行显示。请参考下面的代码:

            [DllImport("user32.dll")]
            private static extern bool ShowWindow(IntPtr hwnd, int nCmdShow);
    
            public App()
            {
                bool isNewInstance;
                string appName = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
                Mutex mtx = new Mutex(true, appName, out isNewInstance);
    
                if (!isNewInstance)
                {
                    Process[] myProcess = Process.GetProcessesByName(Path.GetFileNameWithoutExtension(appName));
                    if (null != myProcess.FirstOrDefault())
                    {
                        ShowWindow(myProcess.FirstOrDefault().MainWindowHandle, 1);
                    }
                    //MessageBox.Show("The app is running now.");
                    Application.Current.Shutdown();
                }
            }

    此时当我们再次运行程序时,会将第一次运行的实例调出来进行显示。比现实“该程序已经运行...”和谐多了。

    博客中代码可以点击这里下载。

    第一次写博客,如果写得不好还望前辈们多多指正。如果博客中有错误的地方欢迎在评论中指出。感谢您的阅读。:)

    Update:

    今天开始写一个新的项目时,也是需要做成单个实例。同样的代码,但是却可以同时运行多个。开发环境Win10 Pro 64bit,但是整个人就凌乱了。后来查阅资料:

    http://stackoverflow.com/questions/19147/what-is-the-correct-way-to-create-a-single-instance-application

    在项目根目录下新建一个Program类,并且将启动项目设置为Program类,代码如下:

        class Program
        {
            [DllImport("user32.dll")]
            private static extern bool ShowWindow(IntPtr hwnd, int nCmdShow);
    
            [STAThread]
            static void Main()
            {
                bool isNewInstance;
                string appName = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
                Mutex mtx = new Mutex(true, appName, out isNewInstance);
    
                if (!isNewInstance)
                {
                    Process[] myProcess = Process.GetProcessesByName(System.IO.Path.GetFileNameWithoutExtension(appName));
                    if (null != myProcess.FirstOrDefault())
                    {
                        ShowWindow(myProcess.FirstOrDefault().MainWindowHandle, 1);
                    }
                    //MessageBox.Show("The app is running now.");
                    //Application.Current.Shutdown();
                    
                }
                else
                {
                    App app = new App();
                    app.Run(new MainWindow());
                }
            }
        }

    记得删除掉原来App中的后台代码。这样就可以完美的完成一个单实例应用程序。

    感激您的阅读,代码点击这里下载。

    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    How to install tcpping on Linux.md
    当前服务器的并发连接数查看
    Windows 系统下安装 dig 命令
    paping使用来测试联通&网站由于tcp协议导致的无法通信问题超时问题
    SSH反向连接及Autossh
    设置Windows Azure Linux虚拟机中的root账户
    用UltraISO制作CentOS U盘安装盘
    CentOS7 修改网卡名称为eth0
    iOS开发--绘图教程
    ios开发--网页中调用JS与JS注入
  • 原文地址:https://www.cnblogs.com/yang-fei/p/3989027.html
Copyright © 2011-2022 走看看