Одиночный экземпляр windows формирует приложение и как получить на него ссылку? - PullRequest
4 голосов
/ 30 марта 2009

У меня есть приложение Windows Forms, которое позволяет одновременно запускать только один экземпляр. Я реализовал синглтон с помощью Mutex. Приложение должно запускаться из командной строки (с параметрами или без них). Приложение запускается и закрывается скриптом. Пользователь не может предпринимать никаких действий с ним.

Итак, целью приложения является простое «индикаторное» приложение, которое будет просто отображать некоторую визуальную и графическую информацию для конечного пользователя. Конечный пользователь не может ничего с этим поделать, просто посмотрите. Это приложение для форм Windows, потому что тогда визуальный и графический внешний вид относительно прост в реализации (вы можете получить его сверху, без полей и т. Д.).

Проще говоря: Как выйти из текущего запущенного приложения, если кто-то пытается запустить то же приложение с параметром командной строки exit?

bool quit = (args.Length > 0 && args[0] == "quit") ? true : false;
using (Mutex mutex = new Mutex(false, sExeName))
{
    if (!mutex.WaitOne(0, true)) 
    {
        if (quit)
        {
            // This is the tricky part?
            // How can I get reference to "previous" launced 
            // Windows Forms application and call it's Exit() method.
        }
    } 
    else 
    {
        if (!quit)
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }
}

Ответы [ 4 ]

6 голосов
/ 31 марта 2009

.NET Framework предлагает очень хорошее общее решение для этого. Проверьте нижнюю часть этой статьи журнала MSDN . Используйте обработчик события StartupNextInstanceHandler () для передачи произвольных команд запущенному экземпляру, например, «quit».

5 голосов
/ 30 марта 2009

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

Process thisProcess = Process.GetCurrentProcess();
        Process[] allProcesses = Process.GetProcessesByName(thisProcess.ProcessName);
        Process otherProcess = null;
        foreach (Process p in allProcesses )
        {
            if ((p.Id != thisProcess.Id) && (p.MainModule.FileName == thisProcess.MainModule.FileName))
            {
                otherProcess = p;
                break;
            }
        }

       if (otherProcess != null)
       {
           //note IntPtr expected by API calls.
           IntPtr hWnd = otherProcess.MainWindowHandle;
           //restore if minimized
           ShowWindow(hWnd ,1);
           //bring to the front
           SetForegroundWindow (hWnd);
       }
        else
        {
            //run your app here
        }

Есть еще один вопрос по этому поводу здесь

1 голос
/ 30 марта 2009

Это довольно быстрое и грязное решение, которое вы, вероятно, захотите усовершенствовать:

[STAThread]
static void Main()
{
    var me = Process.GetCurrentProcess();
    var otherMe = Process.GetProcessesByName(me.ProcessName).Where(p => p.Id != me.Id).FirstOrDefault();

    if (otherMe != null)
    {
        otherMe.Kill();
    }
    else
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }
}

Если экземпляр приложения уже запущен, этот процесс завершается; в противном случае приложение запускается нормально.

0 голосов
/ 15 февраля 2012

Я думаю, что самый простой способ следующий

см. Ссылку

http://codenicely.blogspot.com/2010/04/creating-forms-object.html

...