Restringir múltiplas instâncias de um aplicativo
-
05-07-2019 - |
Pergunta
Ok, então eu criei o meu c # aplicativo, criado um instalador para ele e tê-lo funcionando instalado na minha máquina.
O problema é que, quando o usuário abre o exe aplicação duas vezes, haverá duas instâncias do aplicativo em execução. Eu só quero uma instância do aplicativo para ser executado a qualquer momento, como eu vou fazer isso?
Obrigado por sua ajuda,
Solução
A técnica comum para isso é criar um Mutex
chamada e verificar a sua presença no arranque da aplicação.
Código de DDJ:
class App : Form
{
Mutex mutex;
App()
{
Text = "Single Instance!";
mutex = new Mutex(false, "SINGLE_INSTANCE_MUTEX");
if (!mutex.WaitOne(0, false))
{
mutex.Close();
mutex = null;
}
}
protected override void Dispose(bool disposing)
{
if (disposing)
mutex.ReleaseMutex();
base.Dispose(disposing);
}
static void Main()
{
App app = new App();
if (app.mutex != null) Application.Run(app);
else MessageBox.Show("Instance already running");
}
}
Outras dicas
i resolveu este problema por este
[STAThread]
static void Main()
{
Process[] result = Process.GetProcessesByName("ApplicationName");
if (result.Length > 1)
{
MessageBox.Show("There is already a instance running.", "Information");
System.Environment.Exit(0);
}
// here normal start
}
é simples, mas eu mal tinha tempo para verificar se há soluções melhores.
Com graças a Srs Allen e Powell :
static void Main()
{
using (Mutex mutex = new Mutex(false, @"Global\" + appGuid)) {
if (!mutex.WaitOne(0, false)) {
string processName = GetProcessName();
BringOldInstanceToFront(processName);
}
else {
GC.Collect();
Application.Run(new Voting());
}
}
}
private static void BringOldInstanceToFront(string processName) {
Process[] RunningProcesses = Process.GetProcessesByName(processName);
if (RunningProcesses.Length > 0) {
Process runningProcess = RunningProcesses[0];
if (runningProcess != null) {
IntPtr mainWindowHandle = runningProcess.MainWindowHandle;
NativeMethods.ShowWindowAsync(mainWindowHandle, (int) WindowConstants.ShowWindowConstants.SW_SHOWMINIMIZED);
NativeMethods.ShowWindowAsync(mainWindowHandle, (int) WindowConstants.ShowWindowConstants.SW_RESTORE);
}
}
}
Eu não sei o ambiente que você está operando, mas algo para manter em mente sobre 'aplicativos de instância única' é como você define de instância única. Se o aplicativo pode ser executado em várias estações de trabalho, ao mesmo tempo, usando uma fonte de dados comum, é que é um problema? Da mesma forma, o que dizer de uma situação de serviços de terminal (ou um "Executar como" situação), onde mais de um usuário é registrado no mesmo computador, quer restringir a aplicação de tal forma que apenas uma instância por usuário, por -computador? Ou você está bem com ele simplesmente ser uma instância por usuário?
A resposta a estas podem levá-lo em uma direção em detrimento de outro. Por exemplo, temos uma aplicação 'de instância única' com o escopo de ser um grupo de computadores. Somente um usuário é permitido dentro desse grupo de estações de trabalho. Conseguimos isso por ter uma mesa em nossa fonte de dados compartilhada que rastreou os usuários conectados no momento. Este é um problema de manutenção que você precisa ter certeza de que a tabela é 100% exato o tempo todo. Manipulação de coisas como falta de energia inesperada na estação de trabalho, deixando "falso" registros nessa tabela levou algum tratamento cuidadoso.