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

C#应用程序在默认情况下可以被多次启动的实例。但有些应用程序需要保证只能启动一个实例,可以通过以下两种方式来实现该需求。

方法一:使用 Mutex 对象控制应用程序启动

Mutex 对象是一种操作系统原语,可控制多个进程或线程执行特定代码的互斥访问。应用程序可以使用 Mutex 类来创建一个已命名的 Mutex 对象,并在不同进程之间共享该对象。当有一个进程创建了该 Mutex 对象时,其他试图创建同名 Mutex 对象的进程会停顿等待,直到前面创建的进程释放了 Mutex 对象。

因此,我们可以通过尝试创建已命名的 Mutex 对象,根据返回值来判断应用程序是否已经运行。若对象已存在,则表明应用程序已运行;否则,表明应用程序未运行。

下面是相关代码示例:

using System.Threading;

static class Program
{
    static Mutex mutex = new Mutex(true, "MyAppMutex");

    [STAThread]
    static void Main()
    {
        if (!mutex.WaitOne(TimeSpan.Zero, true))
        {
            MessageBox.Show("只能运行一个实例");
            return;
        }

        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new MainForm());

        mutex.ReleaseMutex();
    }
}

在上面的代码中,我们创建了全局唯一的 Mutex 对象 “MyAppMutex”,并使用 WaitOne() 方法尝试等待 Mutex 的所有权,等待时间为0,表示立即返回。如果该 Mutex 对象已在其他进程中被持有,则当前进程等待 TimeOut 时间之后再次检查 Mutex 对象的状态,直到 Mutex 对象被释放。在应用程序结束时,我们需要调用 ReleaseMutex() 方法释放 Mutex 对象所有权。

方法二:通过 WCF 端口检查应用程序启动

通过创建一个 WCF 端口并绑定到后台线程中进行监听的方式,我们可以实现检测是否已经有相同的客户端连接来实现禁止应用程序多次启动的效果。具体的代码示例如下:

using System.ServiceModel;

static class Program
{
    static readonly string UniqueAddress = string.Format("net.pipe://localhost/{0}/", typeof(MainForm).GUID);

    [STAThread]
    static void Main()
    {
        using (var channelFactory = new ChannelFactory<ISingleInstance>(CreateBinding(), CreateEndpoint()))
        {
            bool createdNew;
            var mutex = new Mutex(true, typeof(MainForm).GUID.ToString(), out createdNew);
            if (!createdNew)
            {
                channelFactory.CreateChannel().Ping();
                return;
            }

            try
            {
                mutex.ReleaseMutex();
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Application.Run(new MainForm(channelFactory));
            }
            finally
            {
                mutex.Close();
            }
        }
    }

    private static Binding CreateBinding()
    {
        return new NetNamedPipeBinding(NetNamedPipeSecurityMode.None);
    }

    private static EndpointAddress CreateEndpoint()
    {
        return new EndpointAddress(UniqueAddress);
    }

    [ServiceContract]
    public interface ISingleInstance
    {
        [OperationContract(IsOneWay = true)]
        void Ping();
    }

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, IncludeExceptionDetailInFaults = true)]
    public class SingleInstance : ISingleInstance
    {
        public void Ping() { return; }
    }
}

在上面的代码中,创建了一个 GUID 并使用互斥对象来保证只有一个线程实例化该 WCF 端口服务。如果已有一个应用程序实例在运行,当前应用程序将使用 WCF 端口发送 Ping 请求给现有实例,然后直接结束。

在第一个实例关闭前,如果再次试图创建实例,将直接退出。如果该端口未被监听,则当前实例则会完成启动。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C# 禁止应用程序多次启动的实例 - Python技术站

(0)
上一篇 2023年5月15日
下一篇 2023年5月15日

相关文章

  • C#使用Monitor类实现线程同步

    关于“C#使用Monitor类实现线程同步”的完整攻略,以下为具体内容: Monitor类简介 Monitor类属于System.Threading命名空间,它提供了一种同步机制以控制对共享资源的访问。Monitor实现相对于lock语句的优点在于使用了更低层次的同步原语,因此可以更细粒度地控制线程的同步。 Monitor类的基本用法 首先是使用Monito…

    C# 2023年5月15日
    00
  • .NET5控制台程序使用EF连接MYSQL数据库的方法

    下面是详细讲解“.NET5控制台程序使用EF连接MYSQL数据库的方法”的完整攻略: 准备工作 确认已经安装.NET5、EF(Core)等必要的环境和工具。 安装Pomelo.EntityFrameworkCore.MySql(用于支持EF连接MYSQL数据库的驱动程序)。 创建控制台程序 使用dotnet命令行工具创建一个新的.NET5控制台程序: dot…

    C# 2023年5月31日
    00
  • 解析WPF实现音频文件循环顺序播放的解决方法

    WPF是一种用于创建Windows桌面应用程序的技术,可以实现音频文件的播放。以下是解析WPF实现音频文件循环顺序播放的解决方法的完整攻略。 环境准备 在使用WPF播放音频文件前,需要在项目中添加NAudio库。可以使用以下命令来添加NAudio库: <PackageReference Include="NAudio" Versio…

    C# 2023年5月15日
    00
  • 一步步教你如何创建第一个C#项目

    一步步教你如何创建第一个C#项目 在本篇攻略中,我们将一步步地创建一个C#控制台程序。这个项目的功能是输出一个简单的问候语句。接下来我们将逐一介绍。 步骤一:打开Visual Studio 首先,你需要打开Visual Studio。可以在Windows操作系统中通过点击Windows菜单键,输入“Visual Studio”进行搜索并进入该程序;或者通过桌…

    C# 2023年6月6日
    00
  • c#使用csredis操作redis的示例

    C# 使用 CSRedis 操作 Redis 的示例攻略 Redis 是一种高性能的键值存储数据库,而 CSRedis 是一个 C# 的 Redis 客户端库,可以方便地在 C# 应用程序中使用 Redis。本攻略将介绍如何使用 CSRedis 操作 Redis,并提供两个示例说明。 步骤 步骤1:安装 CSRedis 首先,我们需要安装 CSRedis。可…

    C# 2023年5月17日
    00
  • C#.NET实现网页自动登录的方法

    下面我会详细讲解如何使用C#.NET实现网页自动登录的方法。 一、需要用到的工具和技术 HttpWebRequest类:C#中提供的Http请求发送类,用于请求Web页面并获取响应数据。 CookieContainer类:C#中提供的Cookie容器,用于管理发送和接收的Cookie信息。 HtmlAgilityPack类库:第三方类库,用于解析HTML文本…

    C# 2023年6月1日
    00
  • C#使用round函数四舍五入的方法

    使用round()函数可以轻松实现C#四舍五入的功能。下面是使用round()函数四舍五入的方法的完整攻略: 1. round()函数用法 在C#中,round()函数是一个标准库函数,用于对数值进行四舍五入。该函数的语法如下: Math.Round(double value, int digits, MidpointRounding mode); 其中,v…

    C# 2023年6月8日
    00
  • Net Core全局配置读取管理方法ConfigurationManager

    在本文中,我们将详细讲解如何在.NET Core中使用ConfigurationManager全局配置读取管理方法,并提供两个示例说明。 准备工作 在开始之前,您需要安装以下软件: .NET Core SDK 使用ConfigurationManager读取配置 在.NET Core项目中添加System.Configuration.Configuratio…

    C# 2023年5月16日
    00
合作推广
合作推广
分享本页
返回顶部