J'ai une application console en C # et je souhaite restreindre mon application à exécuter une seule instance à la fois. Comment y parvenir en C #?
Réponses
Trop de publicités?J'utiliserais un Mutex
static void Main()
{
string mutex_id = "MY_APP";
using (Mutex mutex = new Mutex(false, mutex_id))
{
if (!mutex.WaitOne(0, false))
{
MessageBox.Show("Instance Already Running!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand);
return;
}
// Do stuff
}
}
Si vous décidez d'utiliser un Mutex à cette fin, il y a quelques pièges que vous devez être conscient:
Si vous souhaitez limiter l'application d'une instance par la machine (pas un par utilisateur connecté), alors vous aurez besoin de votre nom de mutex pour démarrer avec le préfixe
Global\
. Si vous n'ajoutez pas de ce préfixe, une instance différente de la mutex sera créé par le système d'exploitation pour chaque utilisateur.Si vous êtes en cours d'exécution sur un Win7/Vista la machine avec le contrôle de compte d'utilisateur est activé, et par chance, l'application en cours d'instance est en cours d'exécution en tant qu'administrateur, puis la prochaine différentes instances ne peuvent pas le détecter, et vous obtiendrez l'autorisation des exceptions. Pour éviter cela, vous devez définir les autorisations pour le Mutex lors de sa création.
Il existe de nombreuses façons, comme -
- L'énumération de la liste des processus avant de commencer et de négation du démarrage si le nom existe déjà.
- La création d'un mutex au démarrage et vérifier si le mutex existe déjà.
- Le lancement d'un programme au moyen d'une classe singleton.
Chacun est démontré ci-dessous:
http://iridescence.no/post/CreatingaSingleInstanceApplicationinC.aspx
http://www.codeproject.com/KB/cs/restricting_instances.aspx
http://www.codeproject.com/KB/cs/singleinstance.aspx
Chacun a ses avantages et inconvénients. Mais je crois que la création de mutex est le meilleur pour aller.
voici une solution qui a fonctionné pour moi
private static bool AlreadyRunning()
{
Process[] processes = Process.GetProcesses();
Process currentProc = Process.GetCurrentProcess();
foreach (Process process in processes)
{
try
{
if (process.Modules[0].FileName == System.Reflection.Assembly.GetExecutingAssembly().Location
&& currentProc.Id != process.Id)
return true;
}
catch (Exception)
{
}
}
return false;
}
Je vérifie ensuite la sortie de cette méthode au démarrage du programme.