Мое приложение должно вести себя немного по-другому, когда оно загружается, если уже существует выполнение экземпляра.
Я понимаю, как использовать взаимное исключение для предотвращения дополнительной загрузки экземпляров, но это не вполне решает мою проблему.
Например:
Какие-либо идеи? К счастью это не должно иметь дело с многопользовательскими учетными записями или чем-либо как этот.
(C#, настольное приложение)
Править: Для разъяснения приложение не должно быть ограничено единственным экземпляром, просто выполните немного отличающееся действие запуска, если существует другой экземпляр, уже работающий. Несколько экземпляров прекрасны (и ожидаются).
Это, вероятно, сделает именно то, что вы хотите. У него есть приятная дополнительная функция, заключающаяся в переносе уже запущенного экземпляра вперед.
РЕДАКТИРОВАТЬ: обновил код, чтобы автоматически определять заголовок приложения.
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;
Другой подход заключается в обнаружении запущенного экземпляра, как подробно описано в блоге Скотта Хансельмана
Его пример активирует первый экземпляр при попытке второго.
Однако было бы несложно заставить второй экземпляр просто остановиться, если бы вы этого хотели.
Не могли бы вы просто проверить 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
)