C#[Win32&WinCE&WM]应用程序只能运行一个实例:MutexHelper

前言

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

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

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

普通 C# 应用程序

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

1. 使用 System.Threading.Mutex 类

参考:Mutex 类(System.Threading)

Copy Highlighter-hljs code-theme-dark
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

Copy Highlighter-hljs code-theme-dark
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实现的,下面是封装的帮助类:

参考:

Copy Highlighter-hljs code-theme-dark
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; } }}

示例代码

调用示例:

Copy Highlighter-hljs code-theme-dark
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... } } }}
posted @   CodeHsu  阅读(635)  评论(1编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示