Accueil > > > INSTANCE UNIQUE D'UNE APPLICATION
INSTANCE UNIQUE D'UNE APPLICATION
Information sur la source
Description
La demande revenant souvent sur les forums (et ayant cherché moi-même par le passé), j'ai développé une classe permettant de gérer le fait qu'une application ne doit être lancée qu'une seule fois. Son utilisation est très simple, il suffit de construire un objet UniqueInstance, en passant en paramètre le port de communication à utiliser, le message à communiquer si une application est déjà lancée, et les actions à effectuer lorsqu'une nouvelle instance a essayé d'être lancée (typiquement, passer l'application courante en premier-plan).
Source
- import java.io.IOException;
- import java.io.PrintWriter;
- import java.net.ServerSocket;
- import java.net.Socket;
- import java.util.Scanner;
- import java.util.logging.Logger;
-
- /**
- * Cette classe permet d'assurer l'unicité de l'instance de l'application. Deux applications ne peuvent pas être lancées
- * simultanément. Voici un exemple typique d'utilisation :
- *
- * <pre>
- * // Port à utiliser pour communiquer avec l'instance de l'application lancée.
- * final int PORT = 32145;
- * // Message à envoyer à l'application lancée lorsqu'une autre instance essaye de démarrer.
- * final String MESSAGE = "nomDeMonApplication";
- * // Actions à effectuer lorsqu'une autre instance essaye de démarrer.
- * final Runnable RUN_ON_RECEIVE = new Runnable() {
- * public void run() {
- * if(mainFrame != null) {
- * // Si la fenêtre n'est pas visible (uniquement dans le systray par exemple), on la rend visible.
- * if(!mainFrame.isVisible())
- * mainFrame.setVisible(true);
- * // On demande à la mettre au premier plan.
- * mainFrame.toFront();
- * }
- * }
- * });
- *
- * UniqueInstance uniqueInstance = new UniqueInstance(PORT, MESSAGE, RUN_ON_RECEIVE);
- * // Si aucune autre instance n'est lancée...
- * if(uniqueInstance.launch()) {
- * // On démarre l'application.
- * new MonApplication();
- * }
- * </pre>
- *
- * @author rom1v
- */
- public class UniqueInstance {
-
- /** Port d'écoute utilisé pour l'unique instance de l'application. */
- private int port;
-
- /** Message à envoyer à l'éventuelle application déjà lancée. */
- private String message;
-
- /** Actions à effectuer lorsqu'une autre instance de l'application a indiqué qu'elle avait essayé de démarrer. */
- private Runnable runOnReceive;
-
- /**
- * Créer un gestionnaire d'instance unique de l'application.
- *
- * @param port
- * Port d'écoute utilisé pour l'unique instance de l'application.
- * @param message
- * Message à envoyer à l'éventuelle application déjà lancée, {@code null} si aucune action.
- * @param runOnReceive
- * Actions à effectuer lorsqu'une autre instance de l'application a indiqué qu'elle avait essayé de
- * démarrer, {@code null} pour aucune action.
- */
- public UniqueInstance(int port, String message, Runnable runOnReceive) {
- assert port > 0 && port < 1 << 16 : "Le port doit être entre 1 et 65535";
- assert message != null || runOnReceive == null : "Il y a des actions à effectuer => le message ne doit pas être null.";
- this.port = port;
- this.message = message;
- this.runOnReceive = runOnReceive;
- }
-
- /**
- * Créer un gestionnaire d'instance unique de l'application. Ce constructeur désactive la communication entre
- * l'instance déjà lancée et l'instance qui essaye de démarrer.
- *
- * @param port
- * Port d'écoute utilisé pour l'unique instance de l'application.
- */
- public UniqueInstance(int port) {
- this(port, null, null);
- }
-
- /**
- * Essaye de démarrer le gestionnaire d'instance unique. Si l'initialisation a réussi, c'est que l'instance est
- * unique. Sinon, c'est qu'une autre instance de l'application est déjà lancée. L'appel de cette méthode prévient
- * l'application déjà lancée qu'une autre vient d'essayer de se connecter.
- *
- * @return {@code true} si l'instance de l'application est unique.
- */
- public boolean launch() {
- /* Indique si l'instance du programme est unique. */
- boolean unique;
-
- try {
- /* On crée une socket sur le port défini. */
- final ServerSocket server = new ServerSocket(port);
-
- /* Si la création de la socket réussit, c'est que l'instance du programme est unique, aucune autre n'existe. */
- unique = true;
-
- /* Si il y a des actions à faire lorsqu'une autre instance essaye de démarrer... */
- if(runOnReceive != null) {
-
- /* On lance un Thread d'écoute sur ce port. */
- Thread portListenerThread = new Thread() {
-
- @Override public void run() {
- /* Tant que l'application est lancée... */
- while(true) {
- try {
- /* On attend qu'une socket se connecte sur le serveur. */
- final Socket socket = server.accept();
-
- /* Si une socket est connectée, on écoute le message envoyé dans un nouveau Thread. */
- new Thread() {
-
- @Override public void run() {
- receive(socket);
- }
- }.start();
- } catch(IOException e) {
- Logger.getLogger("UniqueInstance").warning("Attente de connexion de socket échouée.");
- }
- }
- }
- };
-
- /* Le Thread d'écoute de port est démon. */
- portListenerThread.setDaemon(true);
-
- /* On démarre le Thread. */
- portListenerThread.start();
- }
- } catch(IOException e) {
- /* Si la création de la socket échoue, c'est que l'instance de n'est pas unique, une autre n'existe. */
- unique = false;
-
- /* Si des actions sont prévues par l'instance déjà lancée... */
- if(runOnReceive != null) {
- /*
- * Dans ce cas, on envoie un message à l'autre instance de l'application pour lui demander d'avoir le
- * focus (par exemple).
- */
- send();
- }
- }
- return unique;
- }
-
- /**
- * Envoie un message à l'instance de l'application déjà ouverte.
- */
- private void send() {
- PrintWriter pw = null;
- try {
- /* On se connecte sur la machine locale. */
- Socket socket = new Socket("localhost", port);
-
- /* On définit un PrintWriter pour écrire sur la sortie de la socket. */
- pw = new PrintWriter(socket.getOutputStream());
-
- /* On écrit le message sur la socket. */
- pw.write(message);
- } catch(IOException e) {
- Logger.getLogger("UniqueInstance").warning("Écriture sur flux de sortie de la socket échoué.");
- } finally {
- if(pw != null)
- pw.close();
- }
- }
-
- /**
- * Reçoit un message d'une socket s'étant connectée au serveur d'écoute. Si ce message est le message de l'instance
- * unique, l'application demande le focus.
- *
- * @param socket
- * Socket connecté au serveur d'écoute.
- */
- private void receive(Socket socket) {
- Scanner sc = null;
-
- try {
- /* On n'écoute que 5 secondes, si aucun message n'est reçu, tant pis... */
- socket.setSoTimeout(5000);
-
- /* On définit un Scanner pour lire sur l'entrée de la socket. */
- sc = new Scanner(socket.getInputStream());
-
- /* On ne lit qu'une ligne. */
- String s = sc.nextLine();
-
- /* Si cette ligne est le message de l'instance unique... */
- if(message.equals(s)) {
- /* On exécute le code demandé. */
- runOnReceive.run();
- }
- } catch(IOException e) {
- Logger.getLogger("UniqueInstance").warning("Lecture du flux d'entrée de la socket échoué.");
- } finally {
- if(sc != null)
- sc.close();
- }
-
- }
-
- }
import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
import java.util.logging.Logger;
/**
* Cette classe permet d'assurer l'unicité de l'instance de l'application. Deux applications ne peuvent pas être lancées
* simultanément. Voici un exemple typique d'utilisation :
*
* <pre>
* // Port à utiliser pour communiquer avec l'instance de l'application lancée.
* final int PORT = 32145;
* // Message à envoyer à l'application lancée lorsqu'une autre instance essaye de démarrer.
* final String MESSAGE = "nomDeMonApplication";
* // Actions à effectuer lorsqu'une autre instance essaye de démarrer.
* final Runnable RUN_ON_RECEIVE = new Runnable() {
* public void run() {
* if(mainFrame != null) {
* // Si la fenêtre n'est pas visible (uniquement dans le systray par exemple), on la rend visible.
* if(!mainFrame.isVisible())
* mainFrame.setVisible(true);
* // On demande à la mettre au premier plan.
* mainFrame.toFront();
* }
* }
* });
*
* UniqueInstance uniqueInstance = new UniqueInstance(PORT, MESSAGE, RUN_ON_RECEIVE);
* // Si aucune autre instance n'est lancée...
* if(uniqueInstance.launch()) {
* // On démarre l'application.
* new MonApplication();
* }
* </pre>
*
* @author rom1v
*/
public class UniqueInstance {
/** Port d'écoute utilisé pour l'unique instance de l'application. */
private int port;
/** Message à envoyer à l'éventuelle application déjà lancée. */
private String message;
/** Actions à effectuer lorsqu'une autre instance de l'application a indiqué qu'elle avait essayé de démarrer. */
private Runnable runOnReceive;
/**
* Créer un gestionnaire d'instance unique de l'application.
*
* @param port
* Port d'écoute utilisé pour l'unique instance de l'application.
* @param message
* Message à envoyer à l'éventuelle application déjà lancée, {@code null} si aucune action.
* @param runOnReceive
* Actions à effectuer lorsqu'une autre instance de l'application a indiqué qu'elle avait essayé de
* démarrer, {@code null} pour aucune action.
*/
public UniqueInstance(int port, String message, Runnable runOnReceive) {
assert port > 0 && port < 1 << 16 : "Le port doit être entre 1 et 65535";
assert message != null || runOnReceive == null : "Il y a des actions à effectuer => le message ne doit pas être null.";
this.port = port;
this.message = message;
this.runOnReceive = runOnReceive;
}
/**
* Créer un gestionnaire d'instance unique de l'application. Ce constructeur désactive la communication entre
* l'instance déjà lancée et l'instance qui essaye de démarrer.
*
* @param port
* Port d'écoute utilisé pour l'unique instance de l'application.
*/
public UniqueInstance(int port) {
this(port, null, null);
}
/**
* Essaye de démarrer le gestionnaire d'instance unique. Si l'initialisation a réussi, c'est que l'instance est
* unique. Sinon, c'est qu'une autre instance de l'application est déjà lancée. L'appel de cette méthode prévient
* l'application déjà lancée qu'une autre vient d'essayer de se connecter.
*
* @return {@code true} si l'instance de l'application est unique.
*/
public boolean launch() {
/* Indique si l'instance du programme est unique. */
boolean unique;
try {
/* On crée une socket sur le port défini. */
final ServerSocket server = new ServerSocket(port);
/* Si la création de la socket réussit, c'est que l'instance du programme est unique, aucune autre n'existe. */
unique = true;
/* Si il y a des actions à faire lorsqu'une autre instance essaye de démarrer... */
if(runOnReceive != null) {
/* On lance un Thread d'écoute sur ce port. */
Thread portListenerThread = new Thread() {
@Override public void run() {
/* Tant que l'application est lancée... */
while(true) {
try {
/* On attend qu'une socket se connecte sur le serveur. */
final Socket socket = server.accept();
/* Si une socket est connectée, on écoute le message envoyé dans un nouveau Thread. */
new Thread() {
@Override public void run() {
receive(socket);
}
}.start();
} catch(IOException e) {
Logger.getLogger("UniqueInstance").warning("Attente de connexion de socket échouée.");
}
}
}
};
/* Le Thread d'écoute de port est démon. */
portListenerThread.setDaemon(true);
/* On démarre le Thread. */
portListenerThread.start();
}
} catch(IOException e) {
/* Si la création de la socket échoue, c'est que l'instance de n'est pas unique, une autre n'existe. */
unique = false;
/* Si des actions sont prévues par l'instance déjà lancée... */
if(runOnReceive != null) {
/*
* Dans ce cas, on envoie un message à l'autre instance de l'application pour lui demander d'avoir le
* focus (par exemple).
*/
send();
}
}
return unique;
}
/**
* Envoie un message à l'instance de l'application déjà ouverte.
*/
private void send() {
PrintWriter pw = null;
try {
/* On se connecte sur la machine locale. */
Socket socket = new Socket("localhost", port);
/* On définit un PrintWriter pour écrire sur la sortie de la socket. */
pw = new PrintWriter(socket.getOutputStream());
/* On écrit le message sur la socket. */
pw.write(message);
} catch(IOException e) {
Logger.getLogger("UniqueInstance").warning("Écriture sur flux de sortie de la socket échoué.");
} finally {
if(pw != null)
pw.close();
}
}
/**
* Reçoit un message d'une socket s'étant connectée au serveur d'écoute. Si ce message est le message de l'instance
* unique, l'application demande le focus.
*
* @param socket
* Socket connecté au serveur d'écoute.
*/
private void receive(Socket socket) {
Scanner sc = null;
try {
/* On n'écoute que 5 secondes, si aucun message n'est reçu, tant pis... */
socket.setSoTimeout(5000);
/* On définit un Scanner pour lire sur l'entrée de la socket. */
sc = new Scanner(socket.getInputStream());
/* On ne lit qu'une ligne. */
String s = sc.nextLine();
/* Si cette ligne est le message de l'instance unique... */
if(message.equals(s)) {
/* On exécute le code demandé. */
runOnReceive.run();
}
} catch(IOException e) {
Logger.getLogger("UniqueInstance").warning("Lecture du flux d'entrée de la socket échoué.");
} finally {
if(sc != null)
sc.close();
}
}
}
Conclusion
Exemple d'utilisation...
// Port à utiliser pour communiquer avec l'instance de l'application lancée. final int PORT = 32145; // Message à envoyer à l'application lancée lorsqu'une autre instance essaye de démarrer. final String MESSAGE = "nomDeMonApplication"; // Actions à effectuer lorsqu'une autre instance essaye de démarrer. final Runnable RUN_ON_RECEIVE = new Runnable() { public void run() { if(mainFrame != null) { // Si la fenêtre n'est pas visible (uniquement dans le systray par exemple), on la rend visible. if(!mainFrame.isVisible()) mainFrame.setVisible(true); // On demande à la mettre au premier plan. mainFrame.toFront(); } } }); UniqueInstance uniqueInstance = new UniqueInstance(PORT, MESSAGE, RUN_ON_RECEIVE); // Si aucune autre instance n'est lancée... if(uniqueInstance.launch()) { // On démarre l'application. new MonApplication(); }
Historique
- 28 octobre 2006 14:37:48 :
- problèmes d'espacements dans le code source copié
Sources du même auteur
Sources de la même categorie
Commentaires et avis
Discussions en rapport avec ce code source dans le forum
Unique instance de programme [ par indiana_jules ]
Salut, j'aimerais pouvoir n'avoir qu'une seule instance de mon programme qui tourne. Existe-t-il un moyen propre de le faire ? (sans passer par un Ser
java et une application windows [ par benmor ]
Bonjours à tous,Donc voila mon probleme, j'ai fait une petite application java afin de procèder a des actions répétitives.Cette ap
transformation d'une application java en une applet [ par steflanul ]
bonsoir!! je suis désolé mais je n'arrive toujours pas à transformer mon application en une applet! il me dit toujours apllet non initi
Tester une application J2EE [ par lnp ]
Salut tout le monde,On m'a dit qu'il existe des applications qui testent les applications J2EE...Est-ce que quelqu'un peut me dire où trouver ce
comment configueur un serveur smtp pour une application java (mail) [ par zazou1 ]
salut a tous,vous pouvez m'aidez pour configueur un serveur smtp sur windows XP (pour une application java (e_mail)).merci d'avance.
Deploiment application erreur [ par mael974 ]
Bonjour a tous.g trjs un ti souci lors du deploiement de mon appli (sous tomcat) !! Voici la structure (tres simple) : ds le web_apps jai mon reper
chat/FTP sécurisé [ par kabaouhanen ]
pour réaliser une application chat/FTP sécurisée(cryptographie) quelle est le language le plus convenable pour cette application. Merci
application web I THINK [ par khaledirb7 ]
Je doit développer une applicationen adoptant une architecture trois tiers , je veut utiliser jbuilder comme outil de développementet o
ajax et servlet [ par bf83 ]
bonjour tout le monde,je fais une application avec les servlets et je veux utiliser la notion d'ajax cda l'objet xmlhttprequest .je sais les utilsier
[J2ME] Compilation OK ==> nokia pas OK [ par JuJu ]
Bonjour, j'ai un problème avec une application J2ME. L'application marche à la perfection sur emulateur Wireless toolkit mais est inutilisab
|
Derniers Blogs
MYTIC - SHAREPOINT 2010 : DéJà UN MYTHE MICROSOFT ?MYTIC - SHAREPOINT 2010 : DéJà UN MYTHE MICROSOFT ? par junarnoalg
La prochaine session de MyTIC aura lieu à Namur, le 23 mars prochain. Pendant presque une heure, nous parlerons de SharePoint 2010. Voici un aperçu du programme.
Accueil : 17h30 Début de la session : 18h00 - Les nouvelles int...
Cliquez pour lire la suite de l'article par junarnoalg [MIX10] KEYNOTE DEUXIèME JOURNéE - INTERNET EXPLORER 9, HTML5, VISUAL STUDIO 2010, ODATA[MIX10] KEYNOTE DEUXIèME JOURNéE - INTERNET EXPLORER 9, HTML5, VISUAL STUDIO 2010, ODATA par cyril
Le deuxième keynote du mix fut très riche en contenu. Internet Explorer 9 Juste un après le lancement de Internet Explorer 8, Microsoft a dévoilé les nouveautés de Internet Explorer 9. Désormais, IE supportera HTML5, SVG et CSS3. L'élément ...
Cliquez pour lire la suite de l'article par cyril CERTIFICATIONS BETA .NET 4CERTIFICATIONS BETA .NET 4 par KooKiz
Les inscriptions pour les certifications beta .NET 4 ont commencé. L'inscription est offerte pour les examens suivants : - 71-511, TS: Windows Applications Development with Microsoft .NET Framework 4 - 71-515, TS: Web Applications Development with...
Cliquez pour lire la suite de l'article par KooKiz [MIX 2010] - MICROSOFT TRANSLATOR TECHNOLOGY PREVIEW V2[MIX 2010] - MICROSOFT TRANSLATOR TECHNOLOGY PREVIEW V2 par redo
J'imagine que la plupart d'entre vous connaissent bien et utilisent le service de traduction de Google, mais connaissez-vous celui de Microsoft . Microsoft Translator ? Effectivement, Microsoft nous annoncé le lancement version 2 de la Technologie Preview...
Cliquez pour lire la suite de l'article par redo
Logiciels
Academy System (10.9.4.0)ACADEMY SYSTEM (10.9.4.0)Logiciel de gestion des établissements.
- élèves/étudiants (inscription, dossier, absence...)
-... Cliquez pour télécharger Academy System Xilisoft Convertisseur Vidéo Ultimate (5.1.39.0305)XILISOFT CONVERTISSEUR VIDéO ULTIMATE (5.1.39.0305)Xilisoft Convertisseur Vidéo Ultimate est un outil puissant de conversion vidéo, facile à utilise... Cliquez pour télécharger Xilisoft Convertisseur Vidéo Ultimate Xilisoft DVD Ripper Ultimate (5.0.64.0304)XILISOFT DVD RIPPER ULTIMATE (5.0.64.0304)Xilisoft DVD Ripper Ultimate est un logiciel excellent pour copier et convertir DVD vers presque ... Cliquez pour télécharger Xilisoft DVD Ripper Ultimate Rigs of Rods (63.3)RIGS OF RODS (63.3)c'est un jeu de multi-simulation camions,autobus voitures, avions, bateaux, hélicoptère avec défo... Cliquez pour télécharger Rigs of Rods
|