Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum. Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

EMPECHER UNE APPLIC. DE SE LANCER 2 FOIS


Information sur la source

Catégorie :Astuces Source .NET ( DotNet ) Classé sous : process, instances Niveau : Débutant Date de création : 23/02/2004 Date de mise à jour : 23/02/2004 17:39:29 Vu : 12 005

Note :
9 / 10 - par 4 personnes
9,00 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

Commentaire sur cette source (15)
Ajouter un commentaire et/ou une note


Description

Astuce bien connue de certains et moins d'autres programmeurs pour empêcher une application de se lancer deux fois, il suffit d'agir au niveau des processus.

On parcourt tout d'abord tous les processus actifs, on s'assure que l'ID du processus est bien différente de celle des programmes que l'on compare pour ne ne pas considérer l'application courante comme en doublon avec elle-même puis si le nom des processus est identique, il s'agit bel et bien d'un deuxième lancement.

Pour pouvoir manipuler ces processus, on fait tout d'abord référence à l'espace de noms Diagnostics.
 

Source

  • //******************
  • //En début de code
  • //******************
  • using System.Diagnostics;
  • //******************************************************
  • //Au chargement (Main() ou dans Form_Load() pour applic. Windows
  • //******************************************************
  • //Obtient le processus en cours de l'application
  • Process Proc_EnCours = Process.GetCurrentProcess();
  • //Collection des processus actuellement lancés
  • Process[] Les_Proc = Process.GetProcesses();
  • //Pour chaque processus lancé
  • foreach (Process Processus in Les_Proc)
  • /*Il ne faut pas comparer par rapport à cette instance
  • du programme mais une autre (grâce à l'ID)*/
  • if (Proc_EnCours.Id != Processus.Id)
  • //Si les ID sont différents mais de même nom ==> 2 fois le même programme
  • if (Proc_EnCours.ProcessName == Processus.ProcessName)
  • {
  • MessageBox.Show("Le programme ne peut pas être lancé 2 fois!");
  • this.Close();
  • }
//******************
//En début de code
//******************
using System.Diagnostics;

//******************************************************
//Au chargement (Main() ou dans Form_Load() pour applic. Windows
//******************************************************
//Obtient le processus en cours de l'application
Process Proc_EnCours = Process.GetCurrentProcess();
//Collection des processus actuellement lancés
Process[] Les_Proc = Process.GetProcesses();
//Pour chaque processus lancé
foreach (Process Processus in Les_Proc)
	/*Il ne faut pas comparer par rapport à cette instance
		du programme mais une autre (grâce à l'ID)*/
	if (Proc_EnCours.Id != Processus.Id)
		//Si les ID sont différents mais de même nom ==> 2 fois le même programme
		if (Proc_EnCours.ProcessName == Processus.ProcessName)
		{
		MessageBox.Show("Le programme ne peut pas être lancé 2 fois!");
		this.Close();
		}

Commentaires et avis

signaler à un administrateur
Commentaire de coq le 23/02/2004 20:04:33 administrateur CS

a ta place je mettrais une seconde verif sur le chemin de l'exe, pour etre sur qu'il s'agit bien de ton exe, et pas d'un autre du même nom :
if (Proc_EnCours.ProcessName == Processus.ProcessName && Proc_EnCours.MainModule.FileName == Processus.MainModule.FileName)

signaler à un administrateur
Commentaire de scoubidou944 le 09/03/2004 17:50:52

heu je commence ma migration vers C# mais ca existe pas les mutex ? :

void main (void)
{
HANDLE hMutex;
hMutex = ::CreateMutex (NULL, TRUE, "MyMutexName");
if ((hMutex == NULL) || (::GetLastError() ==ERROR_ALREADY_EXISTS))
{
//"Impossible de créer le mutex"
return;
}

// Blahblah

::CloseHandle (hMutex);
}

signaler à un administrateur
Commentaire de shinkan le 23/05/2004 14:33:18

Bon source, fonctionnel ... mais il serait étonnant que le Framework n'inclut pas une classe permettant de voir si le programme est déjà lancé, comme AppPrevInstance dans VisualBasic 6 ...

signaler à un administrateur
Commentaire de scoubidou944 le 23/05/2004 17:04:44

C'est un poil plus court mais ca reste dans l'esprit du début du topic :

static void Main()
{
Process ThisProcess = Process.GetCurrentProcess();
Process [] AllProcesses = Process.GetProcessesByName(ThisProcess.ProcessName);
if (AllProcesses.Length > 1)
{
// Nothing to do, process already running
}
else
{
Application.Run (new MainForm());
}
}

signaler à un administrateur
Commentaire de JOSEJOSE le 16/12/2004 10:43:12

J'utilise un code qui fonctionne sur mon application et qui n'e m'a jamais fait défaut. Il s'agit donc bien de ce protéger contre un deuxième appel de l'exe.
/// <summary>
/// Entry point of the application
/// </summary>
/// <param name="Args"></param>
public static void Main(string[] Args)
{
// Check if an instance of the application is in progress
if (AppInstanceInProgress())
{
MessageBox.Show("You have an other programm still open. You must run juste ONE at a time.", "Programm Duplicate", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); //***NEW V1.31***
return;
}

try
{
...

/// <summary>
/// Check if a instance of the application is already in progress
/// </summary>
/// <returns></returns>
public static bool AppInstanceInProgress()
{
// Store the current process
Process lproCurrentProcess = Process.GetCurrentProcess();

// Check if the application is already loaded
if (Process.GetProcessesByName(lproCurrentProcess.ProcessName).Length > 1)
{
return true;
}
else
{
return false;
}
return false;
}

signaler à un administrateur
Commentaire de coq le 16/12/2004 11:14:59 administrateur CS

le pb reste entier : un process portant le même nom n'est pas forcement une instance de ton appli (nomme ton appli notepad.exe, lance le bloc note et essaie de lancer ton appli)

un exemple pour les mutex : http://www.thecodeproject.com/csharp/cssingprocess.asp

signaler à un administrateur
Commentaire de scoubidou944 le 16/12/2004 12:15:48

public class MainForm : System.Windows.Forms.Form
{
static  private Mutex g_Mutex;
[STAThread]
static void Main()
{
try
{
g_Mutex = new Mutex(true, "MyMutex");
if (g_Mutex.WaitOne(0,false))
{
// Do the job
}
}
catch (Exception e)
{
}
}
}

signaler à un administrateur
Commentaire de trystan007 le 20/06/2005 19:51:01

Un très bon code, et surtout très utile. N'y aurait-il pas moyen de maximiser la fenêtre déjà existante au lieu d'afficher une dialog box?

signaler à un administrateur
Commentaire de coq le 20/06/2005 21:02:01 administrateur CS

En te servant de la méthode des API Win "ShowWindow" (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/windowing/windows/windowreference/windowfunctions/showwindow.asp) avec la commande "SW_MAXIMIZE" sur le Handle de la fenetre principale de l'appli en question ça doit probablement être faisable.

signaler à un administrateur
Commentaire de fred65200 le 07/07/2005 13:04:24

Un bout de code à améliorer mais qui permet de mettre en premier plan l'appli si elle est déjà lancer
je parle icid'une appli autre que le Form actif

private const int SW_MINIMIZE = 6;
private const int SW_RESTORE = 9;
//Je me suis battu pour savoir quelles constantes il fallait utiliser
//suivant que l'appli est derrière une fenêtre ou dans la barre des tâche

private void button1_Click(object sender, EventArgs e)
  {
      Process[] RunningProcesses = rocess.GetProcessesByName("MonAppli");
      //MonAppli est le nom de l'exe sans .exe
      if (RunningProcesses.Length != 1)
      {
         Process.Start(@"Chemin complet de l'appli");
      }
      else
      {
         ShowWindowAsync(RunningProcesses[0].MainWindowHandle,SW_SHOWMINIMIZED);
         ShowWindowAsync(RunningProcesses[0].MainWindowHandle, SW_RESTORE);
      }
   }
[DllImport("User32.dll")]
public static extern int ShowWindowAsync(IntPtr hWnd, int nCmdShow);


@+

signaler à un administrateur
Commentaire de fred65200 le 07/07/2005 13:07:51

il manque un P

Process[] RunningProcesses = process.GetProcessesByName("MonAppli");

signaler à un administrateur
Commentaire de bucherb le 05/10/2005 15:39:10

Les mutex c'est quand même mieux pour voir si l'appli est déjà démarrée.. Tu y fous un GUID, et t'as vraiment quasiment aucune chance que ça prenne un programme pour un autre.

signaler à un administrateur
Commentaire de bucherb le 05/10/2005 15:49:54

string mutName = "87939A67-2893-470D-82EF-45A525BB31AB";

bool isNew = false;
Mutex mut = new Mutex(false, mutName,out isNew);

if (!isNew) return;

Application.Run(new Form1());

signaler à un administrateur
Commentaire de vladam le 12/08/2006 16:25:05 administrateur CS

bonjour,
Je sais regarder si mon appli est déjà lancée, mais il manque quand même quelquechose dans vos sources :)
J'ai une application de type NOTEPAD mais en MDI. J'empêche donc que mon application démarre deux fois, mais .... dans le cas ou celle-ci est démarrée, je voudrais lui demander de charger le nouveau fichier TXT que j'envois dans le Args[]

Avez vous une solution pour lancer une procédure dans le process qui est déjà lancé ?

Amicalement,

signaler à un administrateur
Commentaire de coq le 12/08/2006 16:44:28 administrateur CS

Salut,

Tu vas devoir passer par un mécanisme d'IPC (Interprocess Communications).
- Remoting
- message Windows "perso" que tu traites par un filtre ou la méthode WndProc (voir WM_APP, WM_USER)
- Data Copy (WM_COPYDATA)
- etc : http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ipc/base/interprocess_communications.asp)

Bon courage :-)

Ajouter un commentaire

Discussions en rapport avec ce code source dans le forum

Lancer un programme a un moment précis [ par Teddysan ] Tout le monde connait le moyen de lancer un programme a partir du code:Process p = new Process();p.StartInfo = new ProcessStartInfo();p.StartInfo.File Execution et gestion de process distant [ par ceoph ] Bonjour,J'aimerais (en winform ou webform) pouvoir lancer un process (executable) avec des options sur une machine distante et la meme chose avec d'au Nom des process [ par bucherb ] Hello!J'aurais besoin de savoir le nom du process de Borland C# Builder et event d'autre Designer (devenv c bon)Je crée des controls qui doivent détec Executer un prgm externe [ par Virtua747 ] J'ai chercher dans le forum et je trouve partout que c'est System.Diagnostics.Process.Start(Path,Arg);Mon problème est que Process est inconnu dans Di Problème avec Process.Start [ par ytse ] Bon j'ai désespérément besoin d'aide.J'essaie d'exécuter des modules .exe via un Web Service.J'utilise donc pour ça Process.Start() (ou encore diverse Gérer une apllication externe (Process) [ par sOuRisoOo ] Bonjour,Je voulais savoir comment je peut faire en C# pour pouvoir: - démarrer une application externe à mon programme - la contrôler (gestion des e Process.StandardOutput [ par sOuRisoOo ] Bonjour !Je voulais savoir quels types de données les processus renvois à travers le StandardOutput, pk j'ai chercher sur MSDN, mais comme je ne compr Process non .net [ par xylogs ] Bonjour,Lorsque je lance un process fils dans mon application C#, j'arrive bien à récupérer les erreurs et les sorties que fait le programme lancé si Petit Probleme [ par MorpionMx ] Bonjour, Je développe une application qui detecte quand internet explorer est lancé, le but etant de pouvoir le controler comme une instance de l'obj Lancer une application... [ par Yandroide ] Salut, Je voudrais pouvoir lancer une appli externe à mon application. Je réussi à le faire avec Process.start... Mon problème est de pouvoir afficher


Nos sponsors

Sondage...

CalendriCode

Décembre 2008
LMMJVSD
1234567
891011121314
15161718192021
22232425262728
293031    

Consulter la suite du CalendriCode



Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel BAÏSE, Merci à Vincent pour ses précieux conseils
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés
Temps d'éxécution de la page : 0,359 sec

Google Coop CodeS-SourceS Google Coop CodeS-SourceS


Certaines images présentes sur le site (notament certains avatars) sont issues des collections IconShock, donc si vous souhaitez utiliser ces icons vous devez les acheter, ne les copiez pas et ne utilisez pas dans vos sites et applications sans les avoir commandé.