Forum des développeurs  

Le forum de référence en programmation et développement. Articles, cours et tutoriels du débutant au chef de projet et DBA confirmé.
Précédent   Forum des développeurs > Dotnet > Visual Basic .NET > Windows Forms

Windows Forms Windows Forms - Forum d'entraide sur la programmation Windows Forms & Applications Windows en Visual Basic .NET. Avant de poster -> Articles Winforms

Réponse
 
Outils de la discussion
Vieux 11/10/2008, 14h25   #1 (permalink)
Modérateur
 
Date d'inscription: mars 2006
Âge: 19
Messages: 1 423
Par défaut ouvrir mon application en cours si on essaie de la lancer une seconde fois

Bonjour,

je vais essayer d'être plus clair que mon titre:
Ce que je veux:
-l'utilisateur lance mon application, il l'utilise, là ok
-l'utilisateur a oublié qu'il a déjà lancé mon application, il essai de la lancer une deuxième foi, là j'ai l'application qui vérifie si elle n'est pas déjà lancée:
Code :
Dim Proc_EnCours As Process = Process.GetCurrentProcess
        Dim Les_Proc() As Process = Process.GetProcesses()
        For Each processus As Process In Les_Proc
            'Il ne faut pas comparer par rapport à cette instance
            'du programme mais une autre (grâce à l'ID)
            If Not Proc_EnCours.Id = processus.Id Then
                'Si les ID sont différents mais de même nom ==> 2 fois le même programme
                If Proc_EnCours.ProcessName = processus.ProcessName Then
 
                    MessageBox.Show("Le programme ne peut pas être lancé 2 fois!")
                    Application.Exit()
                End If
            End If
        Next
Jusque là tout va bien, mais à présent ce que je voudrais, c'est envoyer un truc, je ne sais pas quoi à la première instance, pour qu'elle ouvre la fenetre principale, comme outlook en fait.
Cordialement
__________________
Petit poulain devient grand de jour en jour...

Modérateur .Net

Petit Poulain, ce n'est que pour les intimes!
Poulain est déconnecté   Envoyer un message privé Réponse avec citation
Vieux 11/10/2008, 18h35   #2 (permalink)
Rédacteur/Modérateur
 
Avatar de smyley
 
Date d'inscription: juin 2003
Localisation: Loin
Messages: 3 579
Envoyer un message via MSN à smyley
Par défaut

http://www.codeproject.com/KB/thread...eInstance.aspx
https://secure.codeproject.com/KB/vb/sing_inistan.aspx
https://secure.codeproject.com/KB/vb...&select=228488
__________________
The Place Promised in Our Early Days ...
Distribution d'applications .NET avec DreamShield
DreamShield, Le site, forum, blog, wiki
Mon blog, les blogs DotNet
je ne répondrais aux questions techniques ni par MP ni par email ni par MSN ... le forum est là pour ça
smyley est déconnecté   Envoyer un message privé Réponse avec citation
Vieux 12/10/2008, 09h35   #3 (permalink)
Modérateur
 
Date d'inscription: mars 2006
Âge: 19
Messages: 1 423
Par défaut

je m'y penche dès que possible.
__________________
Petit poulain devient grand de jour en jour...

Modérateur .Net

Petit Poulain, ce n'est que pour les intimes!
Poulain est déconnecté   Envoyer un message privé Réponse avec citation
Vieux 17/10/2008, 11h01   #4 (permalink)
Modérateur
 
Date d'inscription: mars 2006
Âge: 19
Messages: 1 423
Par défaut

J'ai regardé ce que tu m'as donné, rien ne convient.
Mais j'ai trouvé un truc plutôt interressant:
L'événement StartupNextInstance

Mais j'ai un problème, c'est que je n'arrive pas à m'en servir, j'explique:

je démarra mon application par Sub Main. et j'ai l'impression qu'il faut que Startupnextinstance se trouve dans myapplicationevents.vb
Citation:
Le code du gestionnaire d'événements StartupNextInstance est stocké dans le fichier ApplicationEvents.vb, qui est masqué par défaut.
. Ce qui ne convient pas.

J'ai lu aussi que si on démarrait pas une Sub Main, il fallait que la classe qui contient Sub Main hérite de "WindowsFormsApplicationBase", ce que j'ai fait, mais rien n'y fait.

Quand je démarre mon application la première fois, elle se démarre, et quand j'en ouvre ne seconde, elle s'ouvre normalement (comme si ce n'était pas une application single instance). pourtant, j'ai modifié Application.myapp pour avoir
Code XML :
<SingleInstance>true</SingleInstance>
__________________
Petit poulain devient grand de jour en jour...

Modérateur .Net

Petit Poulain, ce n'est que pour les intimes!
Poulain est déconnecté   Envoyer un message privé Réponse avec citation
Vieux 17/10/2008, 11h59   #5 (permalink)
Rédacteur/Modérateur
 
Avatar de smyley
 
Date d'inscription: juin 2003
Localisation: Loin
Messages: 3 579
Envoyer un message via MSN à smyley
Par défaut

Tu es sur que tu as bien regarder https://secure.codeproject.com/KB/vb...&select=228488 ?
Parce que le but de ce code est justement de copier les arguments passés à la nouvelle instance vers l'ancienne ...

Sinon si tu n'en veux vraiment pas il y a le code que j'utilise dans DreamShield (en C# ...) :
Code C# :
 
public delegate void NewInstanceMessageEventHandler(object sender, object message);
 
    public class SingleInstanceApplication
    {
        //win32 translation of APIs, message constants and structures
        private class NativeMethods
        {
            [DllImport("user32.dll")]
            public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
            [DllImport("user32.dll")]
            public static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
 
            public const short WM_COPYDATA = 74;
 
            public struct COPYDATASTRUCT
            {
                public int dwData;
                public int cbData;
                public IntPtr lpData;
            }
        }
 
        //a utility window to communicate between application instances
        private class SIANativeWindow : NativeWindow
        {
            public SIANativeWindow()
            {
                CreateParams cp = new CreateParams();
                cp.Caption = _theInstance._id; //The window title is the same as the Id
                CreateHandle(cp);
            }
 
            //The window procedure that handles notifications from new application instances
            protected override void WndProc(ref Message m)
            {
                if (m.Msg == NativeMethods.WM_COPYDATA)
                {
                    //convert the message LParam to the WM_COPYDATA structure
                    NativeMethods.COPYDATASTRUCT data = (NativeMethods.COPYDATASTRUCT)Marshal.PtrToStructure(m.LParam, typeof(NativeMethods.COPYDATASTRUCT));
                    object obj = null;
                    if (data.cbData > 0 && data.lpData != IntPtr.Zero)
                    {
                        //copy the native byte array to a .net byte array
                        byte[] buffer = new byte[data.cbData];
                        Marshal.Copy(data.lpData, buffer, 0, buffer.Length);
                        //deserialize the buffer to a new object
                        obj = Deserialize(buffer);
                    }
                    _theInstance.OnNewInstanceMessage(obj);
                }
                else
                    base.WndProc(ref m);
            }
        }
 
        //Singleton 
        static SingleInstanceApplication _theInstance = new SingleInstanceApplication();
 
        //this is a uniqe id used to identify the application
        string _id;
        //The is a named mutex used to determine if another application instance already exists
        Mutex _instanceCounter;
        //Is this the first instance?
        bool _firstInstance;
        //Utility window for communication between apps
        SIANativeWindow _notifcationWindow;
 
        private void Dispose()
        {
            //release the mutex handle
            _instanceCounter.Close();
            //and destroy the window
            if (_notifcationWindow != null)
                _notifcationWindow.DestroyHandle();
        }
 
        private void Init()
        {
            _notifcationWindow = new SIANativeWindow();
        }
 
        //returns a uniqe Id representing the application. This is basically the name of the .exe 
        private static string GetAppId()
        {
            #warning SingleInstance Handler Customisé avec un Guid
            return "{107746EE-AD4B-4e7b-B209-CF7F1A93F631}";
        }
 
        //notify event handler
        private void OnNewInstanceMessage(object message)
        {
            if (NewInstanceMessage != null)
                NewInstanceMessage(this, message);
        }
 
        private SingleInstanceApplication()
        {
            //AUDREY
            //_id = "SIA_" + GetAppId();
            _id = "SIA_" + GetAppId();
            _instanceCounter = new Mutex(false, _id, out _firstInstance);
        }
 
        private bool Exists
        {
            get
            {
                return !_firstInstance;
            }
        }
 
        //send a notification to the already existing instance that a new instance was started
        private bool NotifyPreviousInstance(object message)
        {
            //First, find the window of the previous instance
            IntPtr handle = NativeMethods.FindWindow(null, _id);
            if (handle != IntPtr.Zero)
            {
                //create a GCHandle to hold the serialized object. 
                GCHandle bufferHandle = new GCHandle();
                try
                {
                    byte[] buffer;
                    NativeMethods.COPYDATASTRUCT data = new NativeMethods.COPYDATASTRUCT();
                    if (message != null)
                    {
                        //serialize the object into a byte array
                        buffer = Serialize(message);
                        //pin the byte array in memory
                        bufferHandle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
 
                        data.dwData = 0;
                        data.cbData = buffer.Length;
                        //get the address of the pinned buffer
                        data.lpData = bufferHandle.AddrOfPinnedObject();
                    }
 
                    GCHandle dataHandle = GCHandle.Alloc(data, GCHandleType.Pinned);
                    try
                    {
                        NativeMethods.SendMessage(handle, NativeMethods.WM_COPYDATA, IntPtr.Zero, dataHandle.AddrOfPinnedObject());
                        return true;
                    }
                    finally
                    {
                        dataHandle.Free();
                    }
                }
                finally
                {
                    if (bufferHandle.IsAllocated)
                        bufferHandle.Free();
                }
            }
            return false;
        }
 
        //2 utility methods for object serialization\deserialization
        private static object Deserialize(byte[] buffer)
        {
            using (MemoryStream stream = new MemoryStream(buffer))
            {
                return new BinaryFormatter().Deserialize(stream);
            }
        }
 
        private static byte[] Serialize(Object obj)
        {
            using (MemoryStream stream = new MemoryStream())
            {
                new BinaryFormatter().Serialize(stream, obj);
                return stream.ToArray();
            }
        }
 
        public static bool AlreadyExists
        {
            get
            {
                return _theInstance.Exists;
            }
        }
 
        public static bool NotifyExistingInstance(object message)
        {
            if (_theInstance.Exists)
            {
                return _theInstance.NotifyPreviousInstance(message);
            }
            return false;
        }
 
        public static bool NotifyExistingInstance()
        {
            return NotifyExistingInstance(null);
        }
 
        public static void Initialize()
        {
            _theInstance.Init();
        }
 
        public static void Close()
        {
            _theInstance.Dispose();
        }
 
        public static event NewInstanceMessageEventHandler NewInstanceMessage;
    }
 

et ça s'utilise comme suit :
Code C# :
 
[STAThread]
        public static MainForm form = null;
 
        static void Main(string[] args)
        {
            ...
 
            if (SingleInstanceApplication.AlreadyExists &&
                SingleInstanceApplication.NotifyExistingInstance(args))
                return;
            SingleInstanceApplication.Initialize();
            SingleInstanceApplication.NewInstanceMessage += new NewInstanceMessageEventHandler(SingleInstanceApplication_NewInstanceMessage);
            try
            {
                form = new MainForm(args);
            }
            finally
            {
                SingleInstanceApplication.Close();
            }
 
            ...
        }
 
        static void SingleInstanceApplication_NewInstanceMessage(object sender, object message)
        {
            string[] args = null;
            try
            {
                args = (string[])message;
            }
            catch (Exception ex)
            {
                MessageBox.Show(String.Format("Erreur interne, impossible de récupérer les arguments d\'instance\n{0}",
                    ex), "Erreur", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
 
            if (args != null && form != null)
            {
                form.ProcessArguments(args);
                form.Activate();
            }
        }
 

Et form.ProcessArguments se charge de traiter les arguments passés par la nouvelle instance à l'instance déjà existante ...

(Et c'est ce que fait normalement le lien que j'ai posté plus haut)
__________________
The Place Promised in Our Early Days ...
Distribution d'applications .NET avec DreamShield
DreamShield, Le site, forum, blog, wiki
Mon blog, les blogs DotNet
je ne répondrais aux questions techniques ni par MP ni par email ni par MSN ... le forum est là pour ça

Dernière modification par Poulain ; 17/10/2008 à 18h49 Motif: ajout de =C#
smyley est déconnecté   Envoyer un message privé Réponse avec citation
Vieux 17/10/2008, 14h57   #6 (permalink)
AP
Membre éprouvé
 
Avatar de AP
 
Date d'inscription: avril 2002
Localisation: Lyon
Âge: 27
Messages: 490
Envoyer un message via ICQ à AP
Par défaut

Heu la solution est toute simple, c'est une case à cocher dans les propriétés du projet http://www.codeproject.com/KB/vb/vb2005ga.aspx
AP est déconnecté   Envoyer un message privé Réponse avec citation
Vieux 17/10/2008, 18h20   #7 (permalink)
Rédacteur/Modérateur
 
Avatar de smyley
 
Date d'inscription: juin 2003
Localisation: Loin
Messages: 3 579
Envoyer un message via MSN à smyley
Par défaut

Citation:
Envoyé par AP Voir le message
Heu la solution est toute simple, c'est une case à cocher dans les propriétés du projet http://www.codeproject.com/KB/vb/vb2005ga.aspx
Le travail est vraiment mâché en vb.net
__________________
The Place Promised in Our Early Days ...
Distribution d'applications .NET avec DreamShield
DreamShield, Le site, forum, blog, wiki
Mon blog, les blogs DotNet
je ne répondrais aux questions techniques ni par MP ni par email ni par MSN ... le forum est là pour ça
smyley est déconnecté   Envoyer un message privé Réponse avec citation
Vieux 17/10/2008, 18h46   #8 (permalink)
Modérateur
 
Date d'inscription: mars 2006
Âge: 19
Messages: 1 423
Par défaut

Citation:
Envoyé par AP Voir le message
Heu la solution est toute simple, c'est une case à cocher dans les propriétés du projet http://www.codeproject.com/KB/vb/vb2005ga.aspx
Oui, mais pas si on utilise Sub Main
Sinon, pour Smyley, c'est vrai que je pourrais tout mettre en code, mais il y a une solution simple avec le framework, je voulais donc l'utiliser.
Si ce n'est pas possible, je vais devoir faire comme ça.
__________________
Petit poulain devient grand de jour en jour...

Modérateur .Net

Petit Poulain, ce n'est que pour les intimes!
Poulain est déconnecté   Envoyer un message privé Réponse avec citation
NEWS DOTNETFAQs .NETTUTORIELS .NETSOURCES .NETLIVRES .NETOUTILS .NETBLOG .NETDOTNET TV

Réponse

Précédent   Forum des développeurs > Dotnet > Visual Basic .NET > Windows Forms

 
Offres d' emploi informatique sur Lesjeudis.com


Outils de la discussion

Règles de messages
Vous ne pouvez pas créer de nouvelles discussions
Vous ne pouvez pas envoyer des réponses
Vous ne pouvez pas envoyer des pièces jointes
Vous ne pouvez pas modifier vos messages

Les balises BB sont activées : oui
Les smileys sont activés : oui
La balise [IMG] est activée : oui
Le code HTML peut être employé : non
Trackbacks are non
Pingbacks are non
Refbacks are non
Navigation rapide