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# 迭代器分部类与索引器详情

    C#迭代器分部类与索引器是C#语言的两种重要特性,本文将详细讲解它们的使用方法和示例。 迭代器分部类的使用 迭代器分部类是将迭代器(Iterator)功能独立出来的一种分部类,该分部类包含一个枚举(Enumerator)和一个迭代器(Iterator)方法。使用迭代器分部类,可以更方便地进行迭代操作,提高代码的可读性和可维护性。 以下是迭代器分部类的使用示例…

    C# 2023年6月3日
    00
  • C#实现简单过滤非法字符实例

    下面是对该问题的详细讲解: 1.背景介绍 在许多场景下,需要对用户输入的数据进行过滤,以防止非法字符的出现。这时候一个比较常见的做法就是使用正则表达式对用户输入的字符串进行校验,屏蔽非法字符,这样既保证了数据的正确性,也提升了应用程序的安全性。 本篇攻略就是介绍如何使用C#编程语言实现简单的过滤非法字符功能。 2.实现过程 2.1 初步设计 在C#中,我们可…

    C# 2023年6月7日
    00
  • ASP.NET Core使用EF查询数据

    ASP.NET Core使用EF查询数据的完整攻略 在本攻略中,我们将详细讲解如何在ASP.NET Core应用程序中使用Entity Framework Core (EF Core)查询数据,并提供两个示例说明。 步骤一:安装NuGet包 在ASP.NET Core应用程序中使用EF Core查询数据,需要安装Microsoft.EntityFramewo…

    C# 2023年5月17日
    00
  • C# Path.GetRandomFileName – 获取一个随机文件名

    Path.GetRandomFileName 方法是C#中的一个静态方法,其返回一个随机生成的文件名(不包含路径),该方法的作用是用于生成一个随机的文件名,以避免文件名的冲突问题。 使用该方法非常简单,只需要在代码中调用该静态方法即可,该方法的语法格式如下: public static string GetRandomFileName(); 该方法返回一个字…

    C# 2023年4月19日
    00
  • ASP.NET Core Middleware的实现方法详解

    ASP.NET Core Middleware的实现方法详解 在ASP.NET Core中,中间件是一种用于处理HTTP请求和响应的组件。我们可以使用中间件来记录接口的耗时,以便我们可以更好地了解的应用程序的性能。在本攻略中,我们将介绍如何编写一个中间件记录接口的耗时,并提供两示例说明。 实现步骤 以下是在ASP.NET Core中编写一个中间件来记录接口耗…

    C# 2023年5月16日
    00
  • C# BinaryReader.ReadBytes – 读取字节数组

    BinaryReader.ReadBytes 方法是 .NET Framework 内置的一个方法,可以用来从流中读取指定长度的字节,并将其存储在字节数组中。该方法返回一个字节数组,表示从流中读取的数据。 使用该方法需要先创建一个 BinaryReader 实例,该实例包含了一个可以读取的流。然后可以调用 ReadBytes 方法来读取指定长度的字节。该方法…

    C# 2023年4月19日
    00
  • c# 命名空间和程序集

    C# 中的命名空间和程序集是重要概念,理解它们的概念和用法可以帮助程序员更好地组织代码和模块化开发。本篇攻略将全面介绍 C# 中的命名空间和程序集。 命名空间 概念 命名空间是用于组织代码的一种方式。它可以包含类型、变量、常量和其他命名空间。命名空间通过隔离不同的代码区域,避免了名称冲突,在代码模块化中起到了重要的作用。 语法 在 C# 中,使用 names…

    C# 2023年6月7日
    00
  • C#数据绑定(DataBinding)简单实现方法

    C#数据绑定是现代软件开发中的一个非常重要的技术,它可以将各种数据源(例如:数据库、XML文档、Web服务、对象集合等)绑定到用户界面上的不同控件(例如:文本框、标签、列表框、表格等),并且随着数据的更改,控件中的内容也会自动更新。下面介绍C#数据绑定的简单实现方法。 准备工作 在进行数据绑定之前,我们需要创建一个Windows Form应用程序或ASP.N…

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