zoukankan      html  css  js  c++  java
  • C# 禁止应用程序多次启动

         经常我们会有这样的需求,只让应用程序运行一个实体。通常我们的情况是,双击一个exe文件,就运行一个程序的实体,再双击一次这个exe文件,又运行这个应用程序的另一个实体。就拿QQ游戏来说吧,一台电脑上一般只能运行一个QQ游戏大厅(不过以前听说过有双开的外挂)。

    那我们的程序也能像QQ游戏那里禁止多次启动吗,答案是可以的,下面介绍下一个简单的实现方法,那就是Mutex(互斥)

          Mutex(mutual exclusion,互斥)是.Net Framework中提供跨多个线程同步访问的一个类。它非常类似了Monitor类,因为他们都只有一个线程能拥有锁定。而操作系统能够识别有名称的互斥,我们可以给互斥一个唯一的名称,在程序启动之前加一个这样的互斥。这样每次程序启动之前,都会检查这个命名的互斥是否存在。如果存在,应用程序就退出。

    static class Program
    {
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
    bool createdNew;
    //系统能够识别有名称的互斥,因此可以使用它禁止应用程序启动两次
    //第二个参数可以设置为产品的名称:Application.ProductName

    //每次启动应用程序,都会验证名称为SingletonWinAppMutex的互斥是否存在
    Mutex mutex = new Mutex(false, "SingletonWinAppMutex", out createdNew);

    //如果已运行,则在前端显示
    //createdNew == false,说明程序已运行
    if (!createdNew)
    {
    Process instance = GetExistProcess();
    if (instance != null)
    {
    SetForegroud(instance);
    Application.Exit();
    return;
    }
    }
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new MainForm());
    }

    /// <summary>
    /// 查看程序是否已经运行
    /// </summary>
    /// <returns></returns>
    private static Process GetExistProcess()
    {
    Process currentProcess = Process.GetCurrentProcess();
    foreach (Process process in Process.GetProcessesByName(currentProcess.ProcessName))
    {
    if ((process.Id != currentProcess.Id) &&
    (Assembly.GetExecutingAssembly().Location == currentProcess.MainModule.FileName))
    {
    return process;
    }
    }
    return null;
    }

    /// <summary>
    /// 使程序前端显示
    /// </summary>
    /// <param name="instance"></param>
    private static void SetForegroud(Process instance)
    {
    IntPtr mainFormHandle = instance.MainWindowHandle;
    if (mainFormHandle != IntPtr.Zero)
    {
    ShowWindowAsync(mainFormHandle, 1);
    SetForegroundWindow(mainFormHandle);
    }
    }

    [DllImport("User32.dll")]
    private static extern bool SetForegroundWindow(IntPtr hWnd);

    [DllImport("User32.dll")]
    private static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow);
    }



  • 相关阅读:
    洛谷p1017 进制转换(2000noip提高组)
    Personal Training of RDC
    XVIII Open Cup named after E.V. Pankratiev. Grand Prix of Eurasia
    XVIII Open Cup named after E.V. Pankratiev. Grand Prix of Peterhof.
    Asia Hong Kong Regional Contest 2019
    XVIII Open Cup named after E.V. Pankratiev. Grand Prix of Siberia
    XVIII Open Cup named after E.V. Pankratiev. Ukrainian Grand Prix.
    XVIII Open Cup named after E.V. Pankratiev. GP of SPb
    卜题仓库
    2014 ACM-ICPC Vietnam National First Round
  • 原文地址:https://www.cnblogs.com/lexiaoyao/p/2279476.html
Copyright © 2011-2022 走看看