Bezdepbonusu7Программирование: статьи и ответы

Вопрос

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

Автор вопроса: BDeveloperОтветов: 11

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

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

  • Вероятно, вам следует указать язык, фреймворк и/или операционную систему. cletus 24.12.2008
  • Я пометил это как VB.Net, так как My.Application - это функция VB.Net. Keith 24.12.2008
  • Добавлен тег singleton, так как кажется, что это то, что требуется. Abizern 24.12.2008
  • Синглтон управляет одним экземпляром класса в одном экземпляре приложения. Вам нужно что-то CLR/системное, например мьютекс lacop 24.12.2008

single-instance

Ответы

Ответ 1 · рейтинг -1 · Pete OHanlon

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

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

Ответ 2 · рейтинг 8 · Jon Dewees

Это то, что я использовал... (С# в .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();
        }
    }

Ответ 3 · рейтинг 6 · Yuval Peled

В 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.

Ответ 4 · рейтинг 3 · Gordon Bell

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

На вкладке Приложение также можно нажать кнопку Просмотр событий приложения, чтобы создать класс ApplicationEvents.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

Ответ 5 · рейтинг 2 · lacop

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

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

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

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

Ответ 6 · рейтинг 2 · Mark Brackett

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

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

Ответ 7 · рейтинг 2 · cardmagik

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

Ответ 8 · рейтинг 1 · biozinc

Используйте 1_. По сути, 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);
}

Из этого запись:

Ответ 9 · рейтинг 1 · JFV

Если ваше приложение находится в 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

Ответ 10 · Sean

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

Ответ 11 · Cédric Guillemette

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

    [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;
    }

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы