IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Récupérer l'instance du programme déjà lancé


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre régulier
    Homme Profil pro
    Inscrit en
    Juin 2011
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations forums :
    Inscription : Juin 2011
    Messages : 9
    Par défaut Récupérer l'instance du programme déjà lancé
    Bonjour,

    Comme le titre l'indique j'aimerais récupérer l'instance de mon programme s'il est déjà lancé et lui passer un paramètre supplémentaire.

    Pour le moment j'arrive à détecter si mon programme est déjà lancé avec "Mutex" et à récupérer le paramètre en question avec "AppDomain.CurrentDomain.SetupInformation.ActivationArguments.ActivationData[0];" car mon application est une ClickOnce

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
     
    bool createdNew = true;
    using (Mutex mutex = new Mutex(true, "MyApp", out createdNew))
    {
           string selectedFile = ""; 
           if (createdNew)
           {
                if (AppDomain.CurrentDomain.SetupInformation.ActivationArguments.ActivationData != null)
                {
                    selectedFile = AppDomain.CurrentDomain.SetupInformation.ActivationArguments.ActivationData[0];
                 }
                 Cursor.Current = Cursors.WaitCursor;
                 Application.EnableVisualStyles();
                 Application.SetCompatibleTextRenderingDefault(false);
                 Application.Run(new MyApp(selectedFile));
            }
            else
            {
                  Process current = Process.GetCurrentProcess();
                  foreach (Process process in Process.GetProcessesByName(current.ProcessName))
                  {
                       if (process.Id != current.Id)
                       {
                            if (AppDomain.CurrentDomain.SetupInformation.ActivationArguments.ActivationData != null)
                            {
                                    MyApp app = //récup de l'instance ??
                                    selectedFile = AppDomain.CurrentDomain.SetupInformation.ActivationArguments.ActivationData[0];
                                    app.openMessage(selectedFile);
                            }
                            else
                                    SetForegroundWindow(process.MainWindowHandle);
                            break;
                      }
                 }
             }
    }
    J'ai associé un type de fichier à mon projet et donc lorsque je double clique sur ce fichier le programme se lance et ouvre la fenêtre principale et une fenêtre supplémentaire.
    Si le programme est déjà lancé j'aimerais ouvrir juste cette fenêtre supplémentaire mais forcément avec des paramètres qui sont stocké dans ma fenêtre principale.

    Est ce que vous avez une idée de comment je pourrais faire cela ? Voir des liens sur internet que je n'aurais pas vu (car pour l'instant je n'ai pas trouvé mon bonheur... )
    En tout cas merci d'avance !

  2. #2
    Membre Expert
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    2 210
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 2 210
    Par défaut
    Salut,

    Ce n'est pas possible de récupérer l'instance d'un process depuis un autre process.

    Ce que tu cherches à obtenir, c'est une sorte de mémoire partagée (shared memory).
    Des solutions que je vois:
    • mettre en place un système de com inter-process type : Remoting, MSMQ, WCF, ... Mais pour ton besoin, c'est peut-être un peu lourd...
    • utiliser un fichier dans lequel tu stockes ces fameux paramètres (le process principal va écrire, les autres process vont lire)



    Nb: Ton mutex ne sert pas dans ton exemple, non ? Un mutex est utilisé pour faire de la synchronistion entre process. Tu n'en as pas besoin, il me semble.

  3. #3
    Membre régulier
    Homme Profil pro
    Inscrit en
    Juin 2011
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations forums :
    Inscription : Juin 2011
    Messages : 9
    Par défaut
    Citation Envoyé par binoo Voir le message
    Salut,

    Ce n'est pas possible de récupérer l'instance d'un process depuis un autre process.

    Ce que tu cherches à obtenir, c'est une sorte de mémoire partagée (shared memory).
    Des solutions que je vois:
    • mettre en place un système de com inter-process type : Remoting, MSMQ, WCF, ... Mais pour ton besoin, c'est peut-être un peu lourd...
    • utiliser un fichier dans lequel tu stockes ces fameux paramètres (le process principal va écrire, les autres process vont lire)



    Nb: Ton mutex ne sert pas dans ton exemple, non ? Un mutex est utilisé pour faire de la synchronistion entre process. Tu n'en as pas besoin, il me semble.
    Merci pour ta réponse.
    En effet je pense qu'il va falloir que je tire un trait la dessus (du moins pour le moment tant que je ne vois pas comment contourner le problème).

    Malheureusement je sais pas comment stocker les données dans un fichier car j'ai besoin des paramètre généré dans la fenêtre générale pour créer la fenêtre supplémentaire.

    Je vais essayer de voir comment marche le Remoting mais ça n'a pas l'air très facile et comme tu l'as dit je pense que c'est vraiment lourd pour mon application.

    Et tu avais raison pour le Mutex, c'est ma faute j'ai appliqué bêtement un code que j'ai trouve sur internet qui me permettait quand même d'éviter plusieurs instances et puis j'ai rajouté d'autre code qui ont fait que cela ne servait plus à rien...

    Si je trouve une solution je la posterais. Merci encore !

  4. #4
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 197
    Par défaut
    wcf (.net remoting en légèrement plus simple) pour ca c'est quand même lourd !


    un semi bricolage simple :

    au démarrage de ton appli, si un processus en cours est déjà de ton appli tu écrit un fichier dans [Dossier] et tu application.exit
    sinon (= pas déja en cours)
    tu démarre un filesystemwatcher sur [Dossier]

    [Dossier] peut être un sous dossier de ton appli
    quand ton programme se lance pour la 1ère fois tu mets en place le filesystemwatcher, il t'avertira instantanément en cas de changement des fichiers du dossier
    au 2ème démarrage (avec un argument en paramètre si j'ai bien compris)
    tu créé un nouveau fichier (un guid en tant que filename dans le pire des cas) dans le dossier, dans ce fichier tu écris ce que tu veux, comme le chemin du fichier à traiter par exemple ; puis tu sors
    la 1ère instance va recevoir un évènement [fichier créé]
    tu peux alors lire le fichier et faire l'action requise, puis supprimer le fichier

    pour les processus :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    foreach (System.Diagnostics.Process p in System.Diagnostics.Process.GetProcesses()) {
     
        if (p.ProcessName == System.Diagnostics.Process.GetCurrentProcess().ProcessName) {
        ///  
        }
    }
    attention au TSE qui dans ce cas ne va pas fonctionner
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  5. #5
    Membre régulier
    Homme Profil pro
    Inscrit en
    Juin 2011
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations forums :
    Inscription : Juin 2011
    Messages : 9
    Par défaut
    Salut,

    Merci pour ta réponse et désolé pour le temps de la mienne (Fête de la st Jean oblige )
    J'ai donc essayé cette méthode avec le fileSystemWatcher. C'est un très bonne idée ! Je ne connaissais pas ça avant.

    J'ai quand même encore une petit soucis... Lorsque la fenêtre s'ouvre elle reste "sans réponse" (la fenêtre apparaît mais le curseur de la souris est en attente et le contenu n'est pas affiché)

    J'utilise exactement les même paramètres et le même code pour ouvrir une fenêtre supplémentaire lorsque j'ouvre mon programme en double cliquant sur un fichier. Je ne comprends juste pas pourquoi ça ne marche pas avec cette méthode.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    string selectedFile = ""; 
                Process current = Process.GetCurrentProcess();
                foreach (Process process in Process.GetProcessesByName(current.ProcessName))
                {
                    if (process.Id != current.Id)
                    {
                        if (AppDomain.CurrentDomain.SetupInformation.ActivationArguments.ActivationData != null)
                        {
                            // écriture du path dans le dossier
                            string watchedFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetModules()[0].FullyQualifiedName) + @"\DirectoryWatched";
                            string pmNameFile = AppDomain.CurrentDomain.SetupInformation.ActivationArguments.ActivationData[0];
                            string fswNameFile = pmNameFile.Substring(pmNameFile.LastIndexOf("/") + 1).Replace(".pm", ".fsw");
                            FileInfo myFile = new FileInfo(watchedFolder + "\\" + fswNameFile);
                            FileStream fs = myFile.OpenWrite();
                            StreamWriter sw = new StreamWriter(fs);
                            sw.WriteLine(pmNameFile);
                            sw.Close();
                        }
                        else
                            SetForegroundWindow(process.MainWindowHandle);
                        //app exit
                        Application.Exit(); // 
                        current.Kill();
                    }
                }
                if (AppDomain.CurrentDomain.SetupInformation.ActivationArguments.ActivationData != null)
                {
                    selectedFile = AppDomain.CurrentDomain.SetupInformation.ActivationArguments.ActivationData[0];
                }
                Application.Run(new MyForm(selectedFile));
    Est ce que vous avez une idée du problème ? Parce que là je dois avouer que ça me dépasse

  6. #6
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 197
    Par défaut
    quelle fenêtre fige ?

    quand ca fige tu fais pause dans visual studio et tu vois où ca en est dans l'exécution
    sinon tu fais du pas à pas et tu vois quelles lignes sont longues
    ou encore un system.diagnostics.stopwatch (chronomètre)
    une fois le truc long trouvé, voir s'il est possible de le déporter sur un autre (thread ou backgroundworker)
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Récupérer une instance d'un programme
    Par Freud44 dans le forum Général Dotnet
    Réponses: 4
    Dernier message: 31/03/2009, 13h26
  2. Détecter si une instance du programme est déjà lancée
    Par ghassen_73 dans le forum Langage
    Réponses: 1
    Dernier message: 15/03/2008, 15h52
  3. Un programme qui lance quelquechose toute les 50 minutes?
    Par altadeos dans le forum C++Builder
    Réponses: 4
    Dernier message: 12/03/2006, 11h16
  4. [C# - Application] - Récupérer l'instance de l'application.
    Par angusyoung34 dans le forum Windows Forms
    Réponses: 3
    Dernier message: 31/12/2005, 13h45
  5. [Flux] Récupérer la descritption de programmes TV
    Par mickbzh dans le forum XML/XSL et SOAP
    Réponses: 9
    Dernier message: 22/12/2005, 16h03

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo