2009-03-30 5 views
4

J'ai une application Windows Forms qui permet à une seule instance d'être exécutée à la fois. J'ai implémenté Singleton en utilisant Mutex. L'application doit pouvoir être démarrée à partir de la ligne de commande (avec ou sans paramètres). L'application est démarrée et quittée par le script. L'utilisateur ne peut pas effectuer d'action dessus. Ainsi, le but de l'application est simple application "indicateur" qui va juste afficher des informations visuelles et graphiques pour l'utilisateur final. L'utilisateur final ne peut rien faire avec, juste le voir. C'est l'application de formulaires de fenêtres parce que l'apparence visuelle et graphique est relativement facile à mettre en œuvre (vous pouvez l'obtenir le plus haut, sans bordure, etc.). Pour dire les choses simplement: Comment puis-je quitter l'application en cours lorsque quelqu'un essaie d'exécuter la même application avec le paramètre de ligne de commande de sortie?Une fenêtre d'instance unique forme une application et comment y accéder?

bool quit = (args.Length > 0 && args[0] == "quit") ? true : false; 
using (Mutex mutex = new Mutex(false, sExeName)) 
{ 
    if (!mutex.WaitOne(0, true)) 
    { 
     if (quit) 
     { 
      // This is the tricky part? 
      // How can I get reference to "previous" launced 
      // Windows Forms application and call it's Exit() method. 
     } 
    } 
    else 
    { 
     if (!quit) 
     { 
      Application.EnableVisualStyles(); 
      Application.SetCompatibleTextRenderingDefault(false); 
      Application.Run(new Form1()); 
     } 
    } 
} 

Répondre

6

Le framework .NET offre une très bonne solution générique pour cela. Vérifiez le bas de cette MSDN magazine article. Utilisez le gestionnaire d'événements StartupNextInstanceHandler() pour transmettre des commandes arbitraires à l'instance en cours d'exécution, comme "quitter".

+1

Microsoft a détruit un autre lien. Vont-ils apprendre? –

+1

https://blogs.msdn.microsoft.com/tyler_whitney/2005/11/28/single-instance-applications-and-c/ –

+0

Peut-il être fait sans 'Microsoft.VisualBasic'? –

5

Est-ce que ce n'est pas fini de compliquer les choses? Plutôt que de fermer l'instance existante et d'en commencer une nouvelle, ne pouvez-vous pas simplement réactiver l'instance existante? De toute façon autour du code ci-dessous devrait vous donner quelques idées sur la façon de s'y prendre ...?

Process thisProcess = Process.GetCurrentProcess(); 
     Process[] allProcesses = Process.GetProcessesByName(thisProcess.ProcessName); 
     Process otherProcess = null; 
     foreach (Process p in allProcesses) 
     { 
      if ((p.Id != thisProcess.Id) && (p.MainModule.FileName == thisProcess.MainModule.FileName)) 
      { 
       otherProcess = p; 
       break; 
      } 
     } 

     if (otherProcess != null) 
     { 
      //note IntPtr expected by API calls. 
      IntPtr hWnd = otherProcess.MainWindowHandle; 
      //restore if minimized 
      ShowWindow(hWnd ,1); 
      //bring to the front 
      SetForegroundWindow (hWnd); 
     } 
     else 
     { 
      //run your app here 
     } 

Il y a une autre question sur ce here

+0

Il fonctionne! À l'intérieur de 'if (otherProccess! = Null)' j'ai mis: 'MessageBox.Show ("Application déjà en cours d'exécution!"); thisProcess.Kill(); '. Merci –

1

Ceci est une solution peu rapide et sale que vous auriez probablement eu envie d'affiner:

[STAThread] 
static void Main() 
{ 
    var me = Process.GetCurrentProcess(); 
    var otherMe = Process.GetProcessesByName(me.ProcessName).Where(p => p.Id != me.Id).FirstOrDefault(); 

    if (otherMe != null) 
    { 
     otherMe.Kill(); 
    } 
    else 
    { 
     Application.EnableVisualStyles(); 
     Application.SetCompatibleTextRenderingDefault(false); 
     Application.Run(new Form1()); 
    } 
} 

Si une instance de l'application est déjà commencé, ce processus est tué; sinon l'application démarre normalement.