5/28/2007

Single-Instance Apps

Очень часто на форумах встречается одна и таже тема под разными заголовками, например: "Один экземпляр приложения", "Защита от повторного запуска", "Как определить запущено приложение или нет", "Одна копия приложения ... как лучше".
 
В ответ предлагаются разные решения (на основе Mutex, Semaphore и т.п.), но все они не учитывают "подводные камни", о которых сказано в статье "Stream Decorator, Single-Instance Apps" (MSDN Magazine). 
 
В .NET 2.0 есть стандартное решение (см. Figure 5 Using SingleInstanceApplication):
 
static class Program
{
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        SingleInstanceApplication.Run(new Form1(),
            StartupNextInstanceHandler);
    }

    static void StartupNextInstanceHandler(
        object sender, StartupNextInstanceEventArgs e)
    {
        // do whatever you want here with e.CommandLine...
    }
}
Класс SingleInstanceApplication находится в сборке Microsoft.VisualBasic.dll в пространстве имен Microsoft.VisualBasic.ApplicationServices. Правда, эта сборка в C# проекте выглядит необычно, но работает отлично :)
 
 

4 Comments:

Анонимный said...

Всё конечно классно, но как это заставить работать в C# проекте?

Компилятор делает стойку на определение неймспейса:
using Microsoft.VisualBasic.ApplicationServices;

Error 1 The type or namespace name 'ApplicationServices' does not exist in the namespace 'Microsoft.VisualBasic' (are you missing an assembly reference?)

Как это заставили работать в демо проекте я не смог найти...

Анонимный said...

нашёл таки как добавить...

(Project->Add Referense->Microsoft.VisualBasic)

но возник вопрос - а не появится ли грабли, если в целевой системе не будет именно этой версии библиотеки, что я подключил?

Анонимный said...

Приведённый кусок кода неполный, класс SingleInstanceApplication самопальный, а не из "сборки".

public class SingleInstanceApplication : WindowsFormsApplicationBase
{
private SingleInstanceApplication()
{
base.IsSingleInstance = true;
}

public static void Run(Form f, StartupNextInstanceEventHandler startupHandler)
{
SingleInstanceApplication app = new SingleInstanceApplication();
app.MainForm = f;
app.StartupNextInstance += startupHandler;
app.Run(Environment.GetCommandLineArgs());
}
}

Mindberg said...

> класс SingleInstanceApplication самопальный

неожиданное заявление :)