Предотвратить несколько экземпляров данного приложения в .NET? - PullRequest
118 голосов
/ 18 сентября 2008

В .NET, как лучше всего предотвратить одновременную работу нескольких экземпляров приложения? И если нет «наилучшего» метода, какие из предостережений следует учитывать при каждом решении?

Ответы [ 22 ]

2 голосов
/ 18 сентября 2008

В этой статье просто объясняется, как вы можете создать приложение Windows с контролем количества его экземпляров или запустить только один экземпляр. Это очень типичная потребность в бизнес-приложении. Уже есть много других возможных решений, чтобы управлять этим.

http://www.openwinforms.com/single_instance_application.html

1 голос
/ 11 января 2017

Просто используя StreamWriter, как насчет этого?

System.IO.File.StreamWriter OpenFlag = null;   //globally

и

try
{
    OpenFlag = new StreamWriter(Path.GetTempPath() + "OpenedIfRunning");
}
catch (System.IO.IOException) //file in use
{
    Environment.Exit(0);
}
1 голос
/ 18 сентября 2008
1 голос
/ 05 августа 2015

После попытки нескольких решений я вопрос. Я закончил тем, что использовал пример для WPF здесь: http://www.c -sharpcorner.com / UploadFile / f9f215 / как ограничить применение только одним экземпляром /

public partial class App : Application  
{  
    private static Mutex _mutex = null;  

    protected override void OnStartup(StartupEventArgs e)  
    {  
        const string appName = "MyAppName";  
        bool createdNew;  

        _mutex = new Mutex(true, appName, out createdNew);  

        if (!createdNew)  
        {  
            //app is already running! Exiting the application  
            Application.Current.Shutdown();  
        }  

    }          
}  

В приложении. Xaml:

x:Class="*YourNameSpace*.App"
StartupUri="MainWindow.xaml"
Startup="App_Startup"
1 голос
/ 18 сентября 2008

Вы должны использовать System.Diagnostics.Process.

Выезд: http://www.devx.com/tips/Tip/20044

1 голос
/ 28 января 2014

(Примечание: это забавное решение! Оно работает, но для этого используется плохой дизайн GDI +.)

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

private static Bitmap randomName = new Bitmap("my_image.jpg");
1 голос
/ 31 октября 2012

Это код для VB.Net

Private Shared Sub Main()
    Using mutex As New Mutex(False, appGuid)
        If Not mutex.WaitOne(0, False) Then
              MessageBox.Show("Instance already running", "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error)
            Return
        End If

        Application.Run(New Form1())
    End Using
End Sub

Это код для C #

private static void Main()
{
    using (Mutex mutex = new Mutex(false, appGuid)) {
        if (!mutex.WaitOne(0, false)) {
            MessageBox.Show("Instance already running", "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
            return;
        }

        Application.Run(new Form1());
    }
}
0 голосов
/ 12 февраля 2019

Ни один из этих ответов не работал для меня, потому что мне нужно было это для работы под Linux с использованием monodevelop Это прекрасно работает для меня:

Вызовите этот метод, передав ему уникальный идентификатор

    public static void PreventMultipleInstance(string applicationId)
    {
        // Under Windows this is:
        //      C:\Users\SomeUser\AppData\Local\Temp\ 
        // Linux this is:
        //      /tmp/
        var temporaryDirectory = Path.GetTempPath();

        // Application ID (Make sure this guid is different accross your different applications!
        var applicationGuid = applicationId + ".process-lock";

        // file that will serve as our lock
        var fileFulePath = Path.Combine(temporaryDirectory, applicationGuid);

        try
        {
            // Prevents other processes from reading from or writing to this file
            var _InstanceLock = new FileStream(fileFulePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);
            _InstanceLock.Lock(0, 0);
            MonoApp.Logger.LogToDisk(LogType.Notification, "04ZH-EQP0", "Aquired Lock", fileFulePath);

            // todo investigate why we need a reference to file stream. Without this GC releases the lock!
            System.Timers.Timer t = new System.Timers.Timer()
            {
                Interval = 500000,
                Enabled = true,
            };
            t.Elapsed += (a, b) =>
            {
                try
                {
                    _InstanceLock.Lock(0, 0);
                }
                catch
                {
                    MonoApp.Logger.Log(LogType.Error, "AOI7-QMCT", "Unable to lock file");
                }
            };
            t.Start();

        }
        catch
        {
            // Terminate application because another instance with this ID is running
            Environment.Exit(102534); 
        }
    }         
0 голосов
/ 11 января 2017

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

Полная статья: https://blogs.msdn.microsoft.com/oldnewthing/20060620-13/?p=30813

Мы используем именованный мьютекс с фиксированным именем для обнаружения запущена ли другая копия программы. Но это также означает, что злоумышленник может сначала создать мьютекс, тем самым предотвращая нашу программу от бега на всех! Как я могу предотвратить этот тип отказа в обслуживании атака

...

Если злоумышленник работает в том же контексте безопасности, что и ваш программа запущена (или будет запущена), тогда вы ничего не можете сделать. Какое бы «тайное рукопожатие» ты придумал, чтобы определить, другая копия вашей программы запущена, злоумышленник может имитировать ее. Так как он работает в правильном контексте безопасности, он может сделать все, что может сделать «настоящая» программа.

...

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

Попробуйте установить DACL для своего мьютекса, вот способ .NET: https://msdn.microsoft.com/en-us/library/system.security.accesscontrol.mutexsecurity(v=vs.110).aspx

0 голосов
/ 18 июня 2015

Это сработало для меня в чистом C #. try / catch - это когда процесс в списке завершается во время цикла.

using System.Diagnostics;
....
[STAThread]
static void Main()
{
...
        int procCount = 0;
        foreach (Process pp in Process.GetProcesses())
        {
            try
            {
                if (String.Compare(pp.MainModule.FileName, Application.ExecutablePath, true) == 0)
                {
                    procCount++;                        
                    if(procCount > 1) {
                       Application.Exit();
                       return;
                    }
                }
            }
            catch { }
        }
        Application.Run(new Form1());
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...