Как убедиться, что запущен один экземпляр приложения

StackOverflow https://stackoverflow.com/questions/391339

  •  23-08-2019
  •  | 
  •  

Вопрос

Я хочу проверить, когда пользователь дважды щелкает значок приложения, что ни один другой экземпляр этого приложения еще не запущен.

Я прочитал о My.Application, но до сих пор не знаю, что делать.

Это было полезно?

Решение

Наиболее распространенным шаблоном для этого является использование шаблона Singleton.Поскольку вы не указали язык, я предполагаю, что вы здесь имеете в виду C#, а если нет, то принципы в большинстве объектно-ориентированных языков остаются теми же.

Этот статья должна вам помочь.

Другие советы

Это то, что я использовал...(С# в .NET 2.0)

    [STAThread]
    private static void Main(string[] args)
    {
        //this follows best practices on
        //ensuring that this is a single instance app.
        string mutexName = "e50cf829-f6b9-471e-8d9f-67eac3699f09";
        bool grantedOwnership;
        //we prefix the mutexName with "Local\\" to allow this to run under terminal services.
        //The "Local\\" prefix forces this into local user space.
        //If we want to forbid this in TS, use the "Global\\" prefix.
        Mutex singleInstanceMutex = new Mutex(true, "Global\\" + mutexName, out grantedOwnership);
        try
        {
            if (!grantedOwnership)
            {
                MessageBox.Show("Error: X is already running.\n\nYou can only run one copy of X at a time.", "X", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
                Application.Exit();
            }
            else
            {
                Application.Run(new X(args));
            }
        }
        finally
        {
            singleInstanceMutex.Close();
        }
    }

В VB .NET есть IsSingleInstance логическое свойство, которое сделает всю работу за вас.

В VB (взято из здесь):

Public Class Program
        Inherits Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase

       Public Sub New()
            Me.IsSingleInstance = True
        End Sub



End Class

Вот как вы используете его в C# (взято из здесь):

// SingleInstanceApplication.cs
class SingleInstanceApplication : WindowsFormsApplicationBase {

 // Must call base constructor to ensure correct initial 
 // WindowsFormsApplicationBase configuration
 public SingleInstanceApplication() {

  // This ensures the underlying single-SDI framework is employed, 
  // and OnStartupNextInstance is fired
  this.IsSingleInstance = true;
 }
}


// Program.cs
static class Program {
 [STAThread]
 static void Main(string[] args) {
  Application.EnableVisualStyles();
  SingleInstanceApplication application = 
   new SingleInstanceApplication();
  application.Run(args);
 }
}

Обязательно укажите ссылку на Microsoft.VisualBasic.dll в своем проекте.

Откройте свойства проекта (вкладка «Приложение») и проверьте Создать одноэкземплярное приложение вариант.

На вкладке «Приложение» вы также можете нажать кнопку Просмотр событий приложения кнопку, чтобы создать ПриложениеEvents.vb класс, в котором вы можете обработать событие второго экземпляра:

Partial Friend Class MyApplication
    Private Sub MyApplication_StartupNextInstance(ByVal sender As Object, ByVal e As Microsoft.VisualBasic.ApplicationServices.StartupNextInstanceEventArgs) Handles Me.StartupNextInstance
        ' Bring First Instance to Foreground
        e.BringToForeground = True
        ' Pass Second Instance Command Line to First Instance
        AppShared.DoSomethingWithCommandLine(e.CommandLine)
    End Sub
End Class

У Скотта Хансельмана есть хорошая статья на эту тему.Код написан на C#, но я думаю, его будет легко перенести на VB.

http://www.hanselman.com/blog/TheWeeklySourceCode31SingleInstanceWinFormsAndMicrosoftVisualBasicdll.aspx

Вот еще одна статья по этой теме на случай, если она не удовлетворит ваши потребности:

http://www.codeproject.com/KB/cs/cssingprocess.aspx

В VB.NET приложение с одним экземпляром просто флажок на странице свойств проекта.Вы также можете поймать My.Application.StartupNextInstance событие, чтобы ваш единственный экземпляр что-то делал при запуске другой копии.Это можно использовать, например, для MDI-подобного поведения при открытии запрошенного документа в исходном экземпляре.

За кулисами это инкапсулирует значительную часть мьютекса и IPC-слизи — см. WindowsFormApplicationBase - и также может использоваться из C#.

Благодаря приведенным выше советам я узнал, как сделать мое приложение единственным экземпляром, но мне все равно пришлось перейти на другой сайт, чтобы ТОЧНО узнать, как это сделать.Вот простая картинка, как мне это удалось сделать.Это было легко, и я надеюсь, что это поможет другим с такой же потребностью, потому что я уверен, что ОП решил эту проблему 7 лет назад:enter image description here

Использовать Mutex.По сути, Mutex может быть назван строкой и уникален в среде CLR.

Образец кода:

try
{
mutex = Mutex.OpenExisting(mutexName);
//since it hasn’t thrown an exception, then we already have one copy of the app open.
MessageBox.Show(”A copy of Todo 3.0 is already open. Please check your system tray (notification area).”,
“Todo 3.0″, MessageBoxButtons.OK, MessageBoxIcon.Information);
Environment.Exit(0);
}
catch (Exception Ex)
{
//since we didn’t find a mutex with that name, create one
Debug.WriteLine(”Exception thrown:” + Ex.Message + ” Creating a new mutex…”);
mutex = new Mutex(true, mutexName);
}

Из этого почта:

Если ваше приложение создано на VB.NET 2.0–3.5, самый простой способ сохранить работающий единственный экземпляр программы — использовать «Свойства платформы приложений Windows».Чтобы попасть туда, щелкните правой кнопкой мыши имя вашего проекта и выберите «Свойства».После этого установите флажок «Создать одноэкземплярное приложение».

Вы также можете использовать файл ApplicationEvents.vb, чтобы показать пользователю, что он запустил вашу программу во второй раз.Вы можете легко создать/просмотреть это в том же окне свойств, нажав кнопку «Просмотр событий приложения».Внутри вы можете выбрать подменю MyApplication_StartupNextInstance и ввести туда код, например:

Private Sub MyApplication_StartupNextInstance(ByVal sender As Object, ByVal e As Microsoft.VisualBasic.ApplicationServices.StartupNextInstanceEventArgs) Handles Me.StartupNextInstance
    MessageBox.Show("This program is already running.  If you do not see the program running, please check your " _
        & "Windows Task Manager for this program name in the 'Processes' Tab." & vbNewLine & vbNewLine & "WARNING: " _
        & " If you terminate the process, you will terminate the only instance of this program!", My.Application.Info.ProductName.ToString _
        & " is Running!", MessageBoxButtons.OK, MessageBoxIcon.Warning)

End Sub

Позвольте мне знать, если это помогает!JFV

Назначьте своему приложению уникальный идентификатор, например жестко закодированное руководство, и создайте экземпляр Mutex, в котором вы назначите мьютексу этот идентификатор.Если выдается исключение, то это означает, что ваше приложение уже запущено (поскольку ему удалось создать мьютекс)

Я подумал, что будет проще разместить образец прямо здесь, а не ссылку.

    [STAThread]
    static void Main()
    {
        if (!IsAppAlreadyRunning())
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1()); /* Change Form1 for your main Form */
        }
        else
        {
            MessageBox.Show("Application is already running!");
        }
    }

    public static bool IsAppAlreadyRunning()
    {
        Process currentProcess = Process.GetCurrentProcess();
        return (IsAppAlreadyRunning(currentProcess.Id, 
                                    currentProcess.ProcessName));
    }

    private static bool IsAppAlreadyRunning(int ID, string Name)
    {
        bool isAlreadyRunning = false;
        Process[] processes = Process.GetProcesses();
        foreach (Process process in processes)
        {
            if (ID != process.Id)
            {
                if (Name == process.ProcessName)
                {
                    isAlreadyRunning = true;
                    break;
                }
            }
        }
        return isAlreadyRunning;
    }
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top