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#中的依赖注入和IoC容器

    详解C#中的依赖注入和IoC容器 什么是依赖注入 依赖注入(Dependency Injection,简称DI)是一种设计模式,用于减少代码间的耦合关系。在依赖注入中,对象依赖不会被硬编码进对象中,而是由外部的实体注入依赖关系。 在实际开发中,依赖通常指的是对象和组件需要的其他对象或组件。依赖注入可以让代码的设计更加灵活,易于维护和扩展。 IoC容器 在依赖…

    C# 2023年5月31日
    00
  • asp.net中调用winrar实现压缩解压缩的代码

    前置条件 在调用winrar实现压缩解压缩的过程中,需要先确保机器上已经安装了winrar,并且环境变量中已经将winrar的可执行文件路径添加到了path中。同时在使用本方法时,需要在代码中引入System.Diagnostics的命名空间。 压缩文件 在asp.net中调用winrar实现压缩文件,可以使用命令行参数来实现。具体步骤如下: (1)构造压缩…

    C# 2023年6月3日
    00
  • ASP.NET C#中Application的用法教程

    下面是ASP.NET C#中Application的用法教程的完整攻略: 什么是 Application? 在 ASP.NET C# 中,Application 可以理解为全局变量,它在整个应用程序范围内都可用。Application 可以存储和访问应用程序的常用的数据,并在不同的页面和会话之间共享这些数据。 如何使用 Application? 在 C# 中…

    C# 2023年5月15日
    00
  • Java泛型类型通配符和C#对比分析

    Java泛型类型通配符和C#泛型中的通配符有些许不同之处。本文将深入讨论这些不同点,并带来一些示例来加深读者的理解。 1. Java泛型类型通配符 Java泛型类型通配符表示某个范围内的类型参数,但具体是哪个类型参数是未知的。泛型类型通配符用?表示,它可以用来定义泛型方法、泛型类和泛型接口,让代码在编译期间进行类型检查,减少运行时的错误。 1.1 无限制通配…

    C# 2023年6月7日
    00
  • C#开发WinForm清空DataGridView控件绑定的数据

    下面我来详细讲解一下。 1. 背景 在 WinForm 应用程序的开发过程中,经常需要使用 DataGridView 控件来显示数据。当需要清空 DataGridView 控件中显示的数据时,我们可以使用如下两种方法: 将 DataGridView 控件绑定的数据源清空; 遍历 DataGridView 控件中的行并逐一删除。 下面分别介绍这两种方法的实现方…

    C# 2023年5月15日
    00
  • ASP.NET Core 3.0轻量级角色API控制授权库

    ASP.NET Core 3.0轻量级角色API控制授权库攻略 ASP.NET Core 3.0提供了一个轻量级的角色API控制授权库,可以用于控制API的访问权限。本攻略将提供一些示例,演示如何使用ASP.NET Core 3.0轻量级角色API控制授权库。 步骤 步骤1:创建一个新的ASP.NET Core Web API项目 首先,需要创建一个新的AS…

    C# 2023年5月17日
    00
  • C#利用反射来判断对象是否包含某个属性的实现方法

    可以通过反射来动态获取和设置对象的属性值。在C#中,可以使用反射判断某个对象是否包含某个特定属性。下面是使用反射来判断对象是否包含某个属性的实现方法: 1.获取类型对象 使用反射,首先需要获取代表要分析的类型的Type对象。可以通过以下两种方法实现: 使用类型名字符串: Type type = Type.GetType(“命名空间.类名”); 直接通过类类型…

    C# 2023年6月1日
    00
  • c#制作简单启动画面的方法

    下面是详细讲解“C#制作简单启动画面的方法”的攻略。 1. 创建一个空项目 首先,在 Visual Studio 中创建一个空项目,选择 C# 作为开发语言。 2. 添加一个新窗口作为启动画面 在创建好的项目中,右键点击解决方案资源管理器中的项目名称,选择添加,再选择 Windows 窗体,将其命名为 SplashScreenForm。 3. 设置启动画面 …

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