Como se certificar de que não há uma instância do aplicativo está sendo executado

StackOverflow https://stackoverflow.com/questions/391339

  •  23-08-2019
  •  | 
  •  

Pergunta

Eu quero verificar quando o usuário clicar duas vezes sobre o ícone applictaion que nenhuma outra instância deste aplicativo já está em execução.

Eu li sobre My.Application mas eu ainda não sei o que fazer.

Foi útil?

Solução

O padrão mais comum para fazer isso é usar o padrão Singleton. Como você não indicaram uma língua, eu vou assumir que você está se referindo C # aqui -. Se não, os princípios ainda são os mesmos na maioria das linguagens OO

Este artigo deve dar-lhe alguma ajuda.

Outras dicas

Este é algo que eu usei ... (C # no .NET 2.0)

    [STAThread]
    private static void Main(string[] args)
    {
        //this follows best practices on
        //ensuring that this is a single instance app.
        string mutexName = "e50cf829-f6b9-471e-8d9f-67eac3699f09";
        bool grantedOwnership;
        //we prefix the mutexName with "Local\\" to allow this to run under terminal services.
        //The "Local\\" prefix forces this into local user space.
        //If we want to forbid this in TS, use the "Global\\" prefix.
        Mutex singleInstanceMutex = new Mutex(true, "Global\\" + mutexName, out grantedOwnership);
        try
        {
            if (!grantedOwnership)
            {
                MessageBox.Show("Error: X is already running.\n\nYou can only run one copy of X at a time.", "X", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
                Application.Exit();
            }
            else
            {
                Application.Run(new X(args));
            }
        }
        finally
        {
            singleInstanceMutex.Close();
        }
    }

No VB .NET há um IsSingleInstance propriedade booleana que faz o trabalho para você.

Em VB (retirado aqui ):

Public Class Program
        Inherits Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase

       Public Sub New()
            Me.IsSingleInstance = True
        End Sub



End Class

Aqui está como você usá-lo em C # (retirado aqui ):

// SingleInstanceApplication.cs
class SingleInstanceApplication : WindowsFormsApplicationBase {

 // Must call base constructor to ensure correct initial 
 // WindowsFormsApplicationBase configuration
 public SingleInstanceApplication() {

  // This ensures the underlying single-SDI framework is employed, 
  // and OnStartupNextInstance is fired
  this.IsSingleInstance = true;
 }
}


// Program.cs
static class Program {
 [STAThread]
 static void Main(string[] args) {
  Application.EnableVisualStyles();
  SingleInstanceApplication application = 
   new SingleInstanceApplication();
  application.Run(args);
 }
}

Certifique-se de fazer referência ao Microsoft.VisualBasic.dll em seu projeto.

Abra o Project Properties (Tab Aplicação) e verificar o Faça aplicativo de instância única opção.

Na guia aplicativos, você também pode clicar no botão View Application Events , para criar um ApplicationEvents.vb classe onde você pode lidar com o segundo evento instância:

Partial Friend Class MyApplication
    Private Sub MyApplication_StartupNextInstance(ByVal sender As Object, ByVal e As Microsoft.VisualBasic.ApplicationServices.StartupNextInstanceEventArgs) Handles Me.StartupNextInstance
        ' Bring First Instance to Foreground
        e.BringToForeground = True
        ' Pass Second Instance Command Line to First Instance
        AppShared.DoSomethingWithCommandLine(e.CommandLine)
    End Sub
End Class

Scott Hanselman tem bom artigo sobre isso. O código é em C #, mas eu acho que vai ser fácil de portar para VB.

http://www.hanselman.com/blog/TheWeeklySourceCode31SingleInstanceWinFormsAndMicrosoftVisualBasicdll.aspx

Aqui está mais um artigo sobre o tema no caso de que não vai atender às suas necessidades:

http://www.codeproject.com/KB/cs/cssingprocess.aspx

Em VB.NET, um único aplicativo instância é apenas uma caixa de seleção na projeto página de propriedades . Você pode também prender o My.Application.StartupNextInstance evento para ter o seu única instância fazer algo quando outra cópia é iniciado. Isto pode ser usado, por exemplo, para MDI como o comportamento de abrir o documento solicitado na instância original.

Nos bastidores, este encapsula um bom bocado de exclusão mútua e IPC goo - veja WindowsFormApplicationBase -. e pode ser usado a partir de C #, assim

Através das dicas acima, eu descobri como fazer meu aplicativo uma única instância, mas eu ainda tinha que ir para outro site para descobrir exatamente como. Aqui é uma simples imagem como eu consegui fazer isso. Foi fácil-peasy e espero que ajuda os outros com a mesma necessidade, porque eu tenho certeza que o OP resolveu este problema há 7 anos: enter descrição da imagem aqui

Use Mutex. Efetivamente, um Mutex pode ser nomeado com uma corda, e é único em todo o CLR.

Exemplo de código:

try
{
mutex = Mutex.OpenExisting(mutexName);
//since it hasn’t thrown an exception, then we already have one copy of the app open.
MessageBox.Show(”A copy of Todo 3.0 is already open. Please check your system tray (notification area).”,
“Todo 3.0″, MessageBoxButtons.OK, MessageBoxIcon.Information);
Environment.Exit(0);
}
catch (Exception Ex)
{
//since we didn’t find a mutex with that name, create one
Debug.WriteLine(”Exception thrown:” + Ex.Message + ” Creating a new mutex…”);
mutex = new Mutex(true, mutexName);
}

A partir desta pós :

Se seu aplicativo está em VB.NET 2,0-3,5, a maneira mais fácil de manter uma única instância do programa em execução é usando o 'Aplicativo Windows Propriedades quadro'. Para chegar lá, clique com o botão direito sobre o nome do projeto e vá para 'Propriedades'. Uma vez lá, selecione a opção 'Make única instância appliation'.

Você também pode usar o ApplicationEvents.vb para mostrar ao usuário que eles executar o programa uma segunda vez. Você pode criar / vista que facilmente na janela mesmas propriedades, selecionando o botão 'Eventos Ver aplicação'. Dentro de lá, você pode selecionar o sub MyApplication_StartupNextInstance e entrar no código lá, como este:

Private Sub MyApplication_StartupNextInstance(ByVal sender As Object, ByVal e As Microsoft.VisualBasic.ApplicationServices.StartupNextInstanceEventArgs) Handles Me.StartupNextInstance
    MessageBox.Show("This program is already running.  If you do not see the program running, please check your " _
        & "Windows Task Manager for this program name in the 'Processes' Tab." & vbNewLine & vbNewLine & "WARNING: " _
        & " If you terminate the process, you will terminate the only instance of this program!", My.Application.Info.ProductName.ToString _
        & " is Running!", MessageBoxButtons.OK, MessageBoxIcon.Warning)

End Sub

Deixe-me saber se isso ajuda! JFV

Atribuir a sua aplicação algum identificador exclusivo, como um guid codificado e criar uma instância Mutex onde você atribuir o mutex que identificador. Se ele lança uma exceção, em seguida, se os meios a sua aplicação já está em execução (como ele conseguiu com sucesso para criar o mutex)

Eu pensei que seria mais fácil ter a amostra aqui mesmo, em vez de um link.

    [STAThread]
    static void Main()
    {
        if (!IsAppAlreadyRunning())
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1()); /* Change Form1 for your main Form */
        }
        else
        {
            MessageBox.Show("Application is already running!");
        }
    }

    public static bool IsAppAlreadyRunning()
    {
        Process currentProcess = Process.GetCurrentProcess();
        return (IsAppAlreadyRunning(currentProcess.Id, 
                                    currentProcess.ProcessName));
    }

    private static bool IsAppAlreadyRunning(int ID, string Name)
    {
        bool isAlreadyRunning = false;
        Process[] processes = Process.GetProcesses();
        foreach (Process process in processes)
        {
            if (ID != process.Id)
            {
                if (Name == process.ProcessName)
                {
                    isAlreadyRunning = true;
                    break;
                }
            }
        }
        return isAlreadyRunning;
    }
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top