Обнаружение, если другой экземпляр приложения уже работает

Мое приложение должно вести себя немного по-другому, когда оно загружается, если уже существует выполнение экземпляра.

Я понимаю, как использовать взаимное исключение для предотвращения дополнительной загрузки экземпляров, но это не вполне решает мою проблему.

Например:

  • Экземпляр 1 загрузка, получает взаимное исключение.
  • Экземпляр 2 загрузки, не может получить взаимное исключение, знает, что существует другой экземпляр.Пока все хорошо.
  • Экземпляр 1 завершение, выпускает взаимное исключение.
  • Экземпляр 3 загрузки, получает взаимное исключение, не знает, что Экземпляр 2 все еще работает.

Какие-либо идеи? К счастью это не должно иметь дело с многопользовательскими учетными записями или чем-либо как этот.

(C#, настольное приложение)

Править: Для разъяснения приложение не должно быть ограничено единственным экземпляром, просто выполните немного отличающееся действие запуска, если существует другой экземпляр, уже работающий. Несколько экземпляров прекрасны (и ожидаются).

13
задан Andy 7 July 2010 в 06:11
поделиться

4 ответа

Это, вероятно, сделает именно то, что вы хотите. У него есть приятная дополнительная функция, заключающаяся в переносе уже запущенного экземпляра вперед.

РЕДАКТИРОВАТЬ: обновил код, чтобы автоматически определять заголовок приложения.

using System;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;

static void Main()
{
    if (!EnsureSingleInstance())
    {
        return;
    }

    //...
}

static bool EnsureSingleInstance()
{
    Process currentProcess = Process.GetCurrentProcess();

    var runningProcess = (from process in Process.GetProcesses()
                          where
                            process.Id != currentProcess.Id &&
                            process.ProcessName.Equals(
                              currentProcess.ProcessName,
                              StringComparison.Ordinal)
                          select process).FirstOrDefault();

    if (runningProcess != null)
    {
        ShowWindow(runningProcess.MainWindowHandle, SW_SHOWMAXIMIZED);
        SetForegroundWindow(runningProcess.MainWindowHandle);

        return false;
    }

    return true;
}

[DllImport("user32.dll", EntryPoint = "SetForegroundWindow")]
private static extern bool SetForegroundWindow(IntPtr hWnd);

[DllImport("user32.dll")]
private static extern Boolean ShowWindow(IntPtr hWnd, Int32 nCmdShow);

private const int SW_SHOWMAXIMIZED = 3;
12
ответ дан 2 December 2019 в 00:17
поделиться

Другой подход заключается в обнаружении запущенного экземпляра, как подробно описано в блоге Скотта Хансельмана

Его пример активирует первый экземпляр при попытке второго.

Однако было бы несложно заставить второй экземпляр просто остановиться, если бы вы этого хотели.

2
ответ дан 2 December 2019 в 00:17
поделиться

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

Согласно http://msdn.microsoft.com/en-us/library/ms682411%28VS.85%29.aspx ,

Если мьютекс является именованным мьютексом и объект существовал до этой функции вызов, возвращаемое значение - дескриптор для существующий объект, GetLastError возвращает ERROR_ALREADY_EXISTS, bInitialOwner игнорируется, а вызывающий поток не предоставляется право собственности. Однако, если у вызывающего абонента ограниченные права доступа, функция завершится ошибкой с ERROR_ACCESS_DENIED и вызывающий должен использовать OpenMutex функция.

РЕДАКТИРОВАТЬ: Только что понял, что это вопрос C # / .Net, извините.

В .Net используйте конструктор Mutex, который возвращает флаг createdNew, http://msdn.microsoft.com/en-us/library/bwe34f1k%28VS.80%29.aspx :

public Mutex (
    bool initiallyOwned,
    string name,
    out bool createdNew
)
0
ответ дан 2 December 2019 в 00:17
поделиться

Попробуйте использовать семафор вместо мьютекса

1
ответ дан 2 December 2019 в 00:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: