Limitare più istanze di un'applicazione
-
05-07-2019 - |
Domanda
Okay, quindi ho creato la mia applicazione c #, ho creato un programma di installazione per esso e l'ho installato sul mio computer.
Il problema è che quando l'utente apre l'applicazione exe due volte, ci saranno due istanze dell'applicazione in esecuzione. Desidero solo un'istanza dell'applicazione in esecuzione in qualsiasi momento, come posso fare?
Grazie per l'aiuto,
Soluzione
La tecnica comune per questo è creare un Mutex
e verificarne la presenza all'avvio dell'applicazione.
Codice da 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");
}
}
Altri suggerimenti
Ho risolto questo problema con questo
[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
}
è semplice, ma ho appena avuto il tempo di cercare soluzioni migliori.
Grazie a Messaggi. 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);
}
}
}
Non conosco l'ambiente in cui si sta operando, ma qualcosa da tenere a mente sulle "applicazioni a istanza singola" è come si definisce l'istanza singola. Se l'applicazione può essere eseguita su più workstation contemporaneamente, utilizzando un'origine dati comune, è un problema? Allo stesso modo, che dire di una situazione di servizi terminal (o di una situazione "esegui come") in cui più di un utente è connesso allo stesso computer, vuoi limitare l'applicazione in modo tale che solo un'istanza per utente, per-computer? O sei d'accordo con il fatto che sia semplicemente un'istanza per utente?
La risposta a queste potrebbe condurti in una direzione piuttosto che in un'altra. Ad esempio, abbiamo un'applicazione "a istanza singola" con l'ambito come gruppo di computer. È consentito un solo utente all'interno di quel gruppo di workstation. Abbiamo gestito questo con una tabella nella nostra origine dati condivisa che ha tracciato gli utenti attualmente connessi. Questo è un problema di manutenzione in quanto è necessario assicurarsi che la tabella sia sempre accurata al 100%. Gestire cose come interruzioni di corrente impreviste sulla workstation, lasciando "fasullo" i record in quella tabella hanno richiesto una gestione attenta.