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 !

INSTANCE UNIQUE D'UNE APPLICATION


Information sur la source

Catégorie :Astuces Classé sous : unique, instance, application Niveau : Initié Date de création : 26/10/2006 Date de mise à jour : 28/10/2006 14:37:48 Vu : 6 461

Note :
6,5 / 10 - par 2 personnes
6,50 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

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

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é

Commentaires et avis

signaler à un administrateur
Commentaire de indiana_jules le 27/10/2006 09:35:46

Salut,
il est vrai que cela a déjà été demandé, mais, de mon point de vue, cette solution n'est pas la meilleure (en tout cas en  entreprise) car elle nécessiste de connaître un port de communication libre (qu'aucun logiciel protocole utilise, et ca peut devenir fastidieux), et cela peut posser un problème de sécurité.

Tu peux pour palier cela utiliser les propriétés systèmes en y insérant une clé permettant de savoir si une instance ou non de ton programme est en cours. Je l'ai déjà utilisé et cette méthode marche bien, mais il y a juste un défaut : le CTRL + ALT + SUPPR de Windows empêche la réecriture de cette clé à la fin de ton programme. Du coup je ne pouvais plus le relancer.

Néanmoins, ton code a le mérite de fournir une solution.

(je vais faire le pénible, mais il est conseillé de respecter les conventions de documentaiton de Java avec les tags @param, ....)

Voilà, et bonne continuation

signaler à un administrateur
Commentaire de indiana_jules le 27/10/2006 09:38:09

oups autant pour moi pour le codage de la documentaiton, j'avais pas vu toute la source ;p

signaler à un administrateur
Commentaire de Twinuts le 27/10/2006 12:44:34 administrateur CS

Salut,

mais il y a juste un défaut : le CTRL + ALT + SUPPR de Windows empêche la réecriture de cette clé à la fin de ton programme

Il te suffit simplement de creer un ShutdownHook exemple


Runtime.getRuntime().addShutdownHook(new Thread(new Runnable(){
  public void run(){
    System.out.println("Haaaaaaaaa on me kill");
  }
}));

seule les kill -9 à la linux ne sont pas trappable et les ALT+F4 sur une fenetre graphique mais il y a une solution pour ce dernier.

signaler à un administrateur
Commentaire de lrequena le 27/10/2006 13:15:18

bonjour, je ne sais pas si j'ai bien compris le probleme mais il me semble que pour obtenir une instance unique (par JVM) il suffit d'utiliser la methode suivante :

....
private static UniqueInstance uinstance = null;
...
private UniqueInstance(...){ ... }
...
public static UniqueInstance getInstance(...){
    if(uinstance==null) uinstance = new UniqueInstance(...);
    return uinstance;
}
...

Dites moi si je me trompe !! :)

signaler à un administrateur
Commentaire de rom1v le 27/10/2006 13:32:25

@Indiana_jules:
La méthode de mettre une clé dans les propriétés systèmes rend ceci non multiplateforme... Une méthode équivalente est de créer un fichier qui indique si une instance est lancée (et le supprimer à la fermeture). Le problème, c'est si par exemple le programme est tué...

@Twinuts:
Mais si le programme est tué, le problème peut être (en partie) résolu par la méthode du hook pour le shutdown... Mais le problème, c'est que si, par exemple, il y a une panne de courant, et bien, tu pourras plus jamais relancer le logiciel... (à moins de supprimer le fichier).

Après plusieurs discussions sur developpez.com, cette méthode, même si elle a l'inconvénient de connaître un port libre (ce qui n'est que peu génant vu les probabilités), reste la meilleure solution...

@Lrequena:
Il ne s'agit pas d'un singleton, mais d'une instance d'application... Par exemple tu lances java MonApplication plusieurs fois, tu veux n'en avoir qu'un...

signaler à un administrateur
Commentaire de Twinuts le 27/10/2006 13:42:21 administrateur CS

Salut,

je ne conteste en rien la méthode que tu utilise je donne simplement une possibilité à Indiana_jules.
Perso pour la gestion des instances j'utilise du natif qui est une solution comme une autre......

signaler à un administrateur
Commentaire de Ijinn le 30/10/2006 10:42:06

Salut,

Une autre solution consiste à utiliser un verrou sur un fichier donné, avec la méthode suivante :

//--------------------------------------------------------------------//
  File fileLock = new File("Verrou.lock");
  RandomAccessFile raFileLock = new RandomAccessFile(fileLock, "rw");
  
  if (raFileLock.getChannel().tryLock() == null) {
      locked = false;
  }
  else {
      locked = true;
  }
//--------------------------------------------------------------------//

Si on ne libère pas le verrou, celui-ci reste actif tant que la machine virtuelle tourne, et empêche tout autre processus de créer un autre verrou sur le même fichier. De cette façon on peut savoir avec certitude si une instance existe déjà, en testant la valeur de locked. (true si une instance existe déjà)

signaler à un administrateur
Commentaire de rom1v le 31/10/2006 09:51:27

Je n'avais pas pensé à cette solution, elle est en effet pas mal et sûr. Elle ne permet cependant pas de demander le passage au premier plan de l'instance déjà lancée, mais bon, on ne peut pas tout avoir...

signaler à un administrateur
Commentaire de rom1v le 31/10/2006 10:24:55

Merci bien Ijinn j'ai complété mon article: http://rom.developpez.com/java-instance-unique/

signaler à un administrateur
Commentaire de blg81 le 30/11/2006 14:46:27

Heu ... comment passe-t-on des arguments au concurrent pour une nouvelle instance?

Par exemple on appelle:
> uneApplication arg1, arg2 ...

Puis:
> uneApplication arg3, arg4 ...

comment l'instance existante reçoit-elle les arguments du second appel? par exemple, comment dans:
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();
}

passer les nouveaux arguments?

signaler à un administrateur
Commentaire de rom1v le 30/11/2006 18:37:25

Tu ne passes pas d'arguments :(

Dans quel cas as-tu besoin de passer des arguments? Car je ne vois pas pour quel type d'appli on aurait besoin de ça.

Sinon il faut améliorer un peu, et rajouter cette possibilité avec la sérialisation par exemple?

signaler à un administrateur
Commentaire de blg81 le 01/12/2006 05:27:15

"Car je ne vois pas pour quel type d'appli on aurait besoin de ça."

Pourtant la plupart des applications en ont besoin, par exemple quand on clique sur des fichiers .xls depuis l'explorateur Windows ils sont ouverts dans la même instance d'Excel.

Ajouter un commentaire

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 &#224; tous,Donc voila mon probleme, j'ai fait une petite application java afin de proc&#232;der a des actions r&#233;p&#233;titives.Cette ap transformation d'une application java en une applet [ par steflanul ] bonsoir!! je suis d&#233;sol&#233; mais je n'arrive toujours pas &#224; 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&#249; 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&#233;aliser une application chat/FTP s&#233;curis&#233;e(cryptographie) quelle est le language le plus convenable pour cette application. Merci application web I THINK [ par khaledirb7 ] Je doit d&#233;velopper une applicationen adoptant une architecture trois tiers&nbsp;, je veut utiliser jbuilder comme outil de d&#233;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&#232;me avec une application J2ME. L'application marche &#224; la perfection sur emulateur Wireless toolkit mais est inutilisab


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é.