zoukankan      html  css  js  c++  java
  • C#[Win32&WinCE&WM]应用程序只能运行一个实例:MutexHelper

    前言

    在开发应用程序时,通常只让程序运行一个实例。所以,就要判断程序是否已经运行。

    下面是我自己在项目中使用到,封装好的帮助类。有 普通的 C# 应用程序 和 Windows CE 和 Windows Mobile 应用程序使用的方法。

    主要是通过 System.Threading.Mutex 类 和 Win32 API 来实现,下面就是各自的代码,调用示例在最后面。

    普通 C# 应用程序

    主要是 Windows 窗体应用程序和控制台程序。

    1. 使用 System.Threading.Mutex 类

    参考:Mutex 类(System.Threading)

    using System.Threading;
    
    namespace XY.Util.Helper
    {
        /// <summary>
        /// Mutex helper
        /// </summary>
    	public class MutexHelper
        {
            /// <summary>
            /// 判断程序是否已经运行
            /// <param name="assembly">程序集实例</param>
            /// </summary>
            /// <returns>
            /// true: 程序已运行
            /// false: 程序未运行
            /// </returns>
            public static bool IsApplicationOnRun(System.Reflection.Assembly assembly)
            {
                string strAppName = assembly.GetName().Name;
                return IsApplicationOnRun(strAppName);
            }
    
            /// <summary>
            /// 判断程序是否已经运行
            /// <param name="assemblyName">程序名称</param>
            /// </summary>
            /// <returns>
            /// true: 程序已运行
            /// false: 程序未运行
            /// </returns>
            public static bool IsApplicationOnRun(string assemblyName)
            {
                bool ret = false;
                //第一个参数:true--给调用线程赋予互斥体的初始所属权  
                //第一个参数:互斥体的名称  
                //第三个参数:返回值,如果调用线程已被授予互斥体的初始所属权,则返回true
                Mutex mutex = new Mutex(true, assemblyName, out ret);
                return !ret;
            }
    	}
    }
    

    2. 使用 Win32 API

    using System;
    using System.Runtime.InteropServices;
    
    namespace XY.Util.Helper
    {
        /// <summary>
        /// Mutex helper
        /// </summary>
    	public class MutexHelper
        {
            [DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
            public static extern IntPtr OpenMutex(uint dwDesiredAccess, bool bInitialOwner, string lpName);
    
            [DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
            public static extern IntPtr CreateMutex(IntPtr lpMutexAttributes, bool bInitialOwner, string lpName);
    
            /// <summary>
            /// 判断程序是否已经运行
            /// <param name="assembly">程序集实例</param>
            /// </summary>
            /// <returns>
            /// true: 程序已运行
            /// false: 程序未运行
            /// </returns>
            public static bool IsApplicationOnRun(System.Reflection.Assembly assembly)
            {
                string strAppName = assembly.GetName().Name;
                return IsApplicationOnRun(strAppName);
            }
    
            /// <summary>
            /// 判断程序是否已经运行
            /// <param name="assemblyName">程序名称</param>
            /// </summary>
            /// <returns>
            /// true: 程序已运行
            /// false: 程序未运行
            /// </returns>
            public static bool IsApplicationOnRun(string assemblyName)
            {
                bool ret = false;
    
                if (OpenMutex(0x1F0001, false, assemblyName) == IntPtr.Zero)
                {
                    CreateMutex(IntPtr.Zero, false, assemblyName);
                    ret = true;
                }
    
                return ret;
            }
    	}
    }
    

    Windows CE | Windows Mobile 应用程序

    在 Windows CE 和 Windows Mobile 中实现,是通过 Win32 API实现的,下面是封装的帮助类:

    参考:

    using System;
    using System.Runtime.InteropServices;
    
    namespace XY.Util.Helper
    {
        /// <summary>
        /// Mutex helper
        /// </summary>
    	public class MutexHelper
    	{
    		[DllImport("coredll.dll", EntryPoint = "CreateMutex", SetLastError = true)]
    		public static extern IntPtr CreateMutex(IntPtr lpMutexAttributes, bool bInitialOwner, string lpName);
    
    		[DllImport("coredll.dll", EntryPoint = "ReleaseMutex", SetLastError = true)]
    		public static extern bool ReleaseMutex(IntPtr hMutex);
    
    		private const int ERROR_ALREADY_EXISTS = 0183;
    
            /// <summary>
            /// 判断程序是否已经运行
            /// <param name="assembly">程序集实例</param>
            /// </summary>
            /// <returns>
            /// true: 程序已运行
            /// false: 程序未运行
            /// </returns>
            public static bool IsApplicationOnRun(System.Reflection.Assembly assembly)
            {
                string strAppName = assembly.GetName().Name;
                return IsApplicationOnRun(strAppName);
            }
    
            /// <summary>
            /// 判断程序是否已经运行
            /// <param name="assemblyName">程序名称</param>
            /// </summary>
            /// <returns>
            /// true: 程序已运行
            /// false: 程序未运行
            /// </returns>
            public static bool IsApplicationOnRun(string assemblyName)
            {
                IntPtr hMutex = CreateMutex(IntPtr.Zero, true, assemblyName);
                if (hMutex == IntPtr.Zero)
                {
                    throw new ApplicationException("Failure creating mutex: " + Marshal.GetLastWin32Error().ToString("X"));
                }
                if (Marshal.GetLastWin32Error() == ERROR_ALREADY_EXISTS)
                {
                    ReleaseMutex(hMutex);
                    return true;
                }
                return false;
            }
    	}
    }
    

    示例代码

    调用示例:

    using System;
    using System.Reflection;
    using XY.Util.Helper;
    
    namespace MutexTest
    {
        static class Program
        {
            [MTAThread]
            static void Main(string[] args)
            {
                bool run;
    
                //方式一
                run = MutexHelper.IsApplicationOnRun("ApplicationName");
    
                //方式二
                run = MutexHelper.IsApplicationOnRun(Assembly.GetExecutingAssembly());
    
                if (run)
                {
                    // application is running...
                    // Exit.
                }
                else
                {
                    // start application ...
                    // startup...
                }
            }
        }
    }
    
  • 相关阅读:
    CentOS虚拟机和物理机共享文件夹实现
    集训第六周 数学概念与方法 概率 数论 最大公约数 G题
    集训第六周 数学概念与方法 概率 F题
    集训第六周 E题
    集训第六周 古典概型 期望 D题 Discovering Gold 期望
    集训第六周 古典概型 期望 C题
    集训第六周 数学概念与方法 UVA 11181 条件概率
    集训第六周 数学概念与方法 UVA 11722 几何概型
    DAG模型(矩形嵌套)
    集训第五周 动态规划 K题 背包
  • 原文地址:https://www.cnblogs.com/seayxu/p/5807197.html
Copyright © 2011-2022 走看看