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日

相关文章

  • Asp.Net 和 AJAX.Net 的区别第2/2页

    关于”Asp.Net和AJAX.Net的区别”,我们需要先了解它们各自的特点和功能。Asp.Net是一种Web应用程序框架,它能够让开发人员创建出具有交互性和动态特性的Web应用程序。而AJAX.Net是一种Web开发技术,它可以允许页面在不进行重新加载的情况下,更新部分内容,提高了用户体验。 区别在以下几个方面: 数据交互方式 Asp.Net传统的方式是通…

    C# 2023年6月3日
    00
  • Unity Pro 2018.2安装图文详细教程(附安装教程+新功能)

    UnityPro 2018.2安装图文详细教程 步骤一:下载Unity安装包 打开Unity官网,链接:https://unity.com/ 点击右上角的“Get Started”按钮,在下拉菜单中选择“Download Unity” 在下载页选择Unity版本,这里选择“Unity 2018.2.0f2 Personal(个人版)” 如果需要,可以在选项中…

    C# 2023年5月15日
    00
  • asp.net后台注册js的四种方法分享

    下面我将详细讲解asp.net后台注册js的四种方法,希望对你有所帮助。 1. 在aspx的头部使用script标签嵌入javascript代码 这种方法是比较简单的,直接在aspx页面的头部使用script标签嵌入javascript代码即可。示例如下: <head runat="server"> <script ty…

    C# 2023年5月31日
    00
  • asp.net 截取Http请求的实现代码

    当我们需要对Http请求做一些特殊的处理时,我们可能需要截取Http请求。在ASP.NET中,我们可以通过编写HttpModule和HttpHandler来实现对Http请求的截取。 HttpModule实现截取Http请求 1.创建HttpModule 首先,我们需要创建一个继承自System.Web.IHttpModule接口的类。该接口具有两个方法:I…

    C# 2023年5月31日
    00
  • 解析C#中的分部类和分部方法

    解析C#中的分部类和分部方法 在 C# 中,分部类(partial class)和分部方法(partial method)允许将一个类或方法的定义分为多个文件,这样可以更好地组织代码、使代码更易维护。本文将详细讲解如何使用分部类和分部方法。 分部类 定义 分部类指的是一个类的定义被分为多个部分,每个部分可以属于同一命名空间或不同命名空间,并且这些部分用 pa…

    C# 2023年6月7日
    00
  • C#使用foreach语句遍历堆栈(Stack)的方法

    介绍C#使用foreach语句遍历堆栈 (Stack)的方法。 1. Stack类简介 在介绍用foreach语句遍历Stack之前,先简单介绍一下Stack类。在C#的System.Collections命名空间中,有一个名为Stack的类。Stack是一种后进先出(LIFO)的数据结构,可以存储多个对象。其中,堆栈的入栈操作使用 Push方法,而出栈操作…

    C# 2023年6月7日
    00
  • c# 异步编程入门

    C# 异步编程入门 什么是异步编程 异步编程是指在代码执行时,允许在执行某些线程耗时的操作时不会阻塞当前线程的执行,以提高程序的性能和响应速度。在 C# 中,异步编程通常与任务(Task)和异步方法(async/await)一起使用。 使用 async/await 实现异步编程 异步编程最常见的实现方式是使用 async/await 关键字。这两个关键字一起…

    C# 2023年6月6日
    00
  • Visual Studio中根据系统区分引用64位、32位DLL动态库文件的配置方法

    下面是详细讲解“Visual Studio中根据系统区分引用64位、32位DLL动态库文件的配置方法”的完整攻略: 新建Visual Studio项目 在Visual Studio中新建一个C++项目,选择“空项目”。 添加DLL库文件 将需要引用的DLL库文件(或者库文件夹)拷贝到项目文件夹中,并在Visual Studio中将其添加到项目中。右键项目,选…

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