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 :

Surcharge de WndProc dans une application console


Sujet :

C#

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    196
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 196
    Points : 94
    Points
    94
    Par défaut Surcharge de WndProc dans une application console
    Bonjour,
    Je developpe une application console qui tourne en tant que service windows. Elle doit intercepeter les messages Windows tels que la fermeture de session... J'ai regardé dans la FAQ les points relatifs à ce problème: http://faqcsharp.developpez.com/?pag...CatchAllEvents
    et http://faqcsharp.developpez.com/?pag...ueryendsession que j'arrive à faire fonctionner dans une application graphique, mais si j'essaye de transposer dans une application console, le compilateur ne trouve pas System.Windows, ce qui m'empeche d'hériter de la classe Form et de surcharger WndProc.

    Ma question est donc de savoir comment intercepter les messages Windows depuis une application console.
    Faut-il toujours chercher à surcharger la méthode WndProc?

    Merci de votre aide!!!

  2. #2
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    700
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2005
    Messages : 700
    Points : 780
    Points
    780
    Par défaut
    Le compilateur ne trouve pas?

    Sans doute parce ce qu'il faut lui préciser de chercher dans une nouvelle référence
    Par exemple System.Windows.Form

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    196
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 196
    Points : 94
    Points
    94
    Par défaut
    Ben j'ai une erreur sur la ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    using System.Windows.Forms
    qui me lève l'erreur
    Le type ou le nom d'espace de noms 'Windows' n'existe pas dans la classe ou l'espace de noms 'System' (une référence d'assembly est-elle manquante ?)
    Merci de ton aide

  4. #4
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    700
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2005
    Messages : 700
    Points : 780
    Points
    780
    Par défaut
    Ben je m'autoquote

    Dans ton projet, clique droit sur "References" => add Reference => .Net => Choisis "System.Windows.Form"

    Un Using ne veux pas dire ajouter une dll : c'est juste pour racourcir l'appel aux classes

    tu peux faire
    using FORMY = System.Windows.Forms;

    class t{ methode{ FORMY.MessageBox.Show( ".." ); }}

  5. #5
    Expert confirmé
    Avatar de ced600
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Août 2006
    Messages
    3 364
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Août 2006
    Messages : 3 364
    Points : 4 061
    Points
    4 061
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    using FORMY = System.Windows.Forms;
    J'étais en train de me dire qu'avec ce genre de chose on pourrait raconter une histoire en même temps que l'on code
    Pourquoi faire compliqué lorsque l'on peut faire encore plus compliqué.

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    196
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 196
    Points : 94
    Points
    94
    Par défaut
    Effectivement ça marche mieux

    ça compile mais je bloque toujours:
    j'ai une classe correspondant au main:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class Program
    {
        static void Main(string[] args)
        {
            Test test = new Test();
            Thread t = new Thread(new ThreadStart(test.loop));
            t.start();
        }
    }
    et une classe de test:
    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
    public class Test : Form
    {
        protected override void WndProc(ref Message m)
        {
            Console.WriteLine("WndProc");
            base.WndProc(ref m);
        }
     
        public void loop()
        {
            while(true)
            {
                  string str = Console.ReadLine();
                  Console.WriteLine(str);
     
                  if(str.Equals(""))
                      break;
            }
        }
    }
    Résultat, la ligne saisie est bien recopiée () mais la méthode WndProc n'est jamais appelée...

    Merci de ton aide

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    196
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 196
    Points : 94
    Points
    94
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    using FORMY = System.Windows.Forms;
    J'étais en train de me dire qu'avec ce genre de chose on pourrait raconter une histoire en même temps que l'on code
    En tous cas, merci du coup de Main() !!!!

  8. #8
    Expert confirmé
    Avatar de ced600
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Août 2006
    Messages
    3 364
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Août 2006
    Messages : 3 364
    Points : 4 061
    Points
    4 061
    Par défaut
    Juste au cas où :
    Lorsque l'on hérite d'une classe, et que l'on surcharge une méthode.
    Si la méthode de la classe mère est appelé par des events, est on obligé de réassocié la méthode surchargé à ces events pour qu'elle soit appellé ?

    Si non alors c'est qu'aucun event n'appelant ta méthode n'est levé
    Pourquoi faire compliqué lorsque l'on peut faire encore plus compliqué.

  9. #9
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    547
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 547
    Points : 627
    Points
    627
    Par défaut
    Salut Jesus144,

    le comportement est tout à fait normal. Tu lances un threads qui boucle sans fin avec un arret sur un readline, pour lui pas de probleme (ca affiche bien dans la console), pour le thread principal (nota : c'est le createur de ta form), il s'est arreté juste apres avoir créé le second thread, ta form ne sert plus à rien (et in extenso, ton WndProc n'est jamais appelé).

    Tu peux essayer de faire comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
        public class Form1 : Form
        {
            protected override void WndProc(ref Message m)
            {
                Console.WriteLine("WndProc : " + m.Msg);
                base.WndProc(ref m);
            }
        }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
            static void Main()
            {
                Form1 test = new Form1();
                Application.Run(test);
            }
    Tu compiles le tout pour un exe console, et tu as bien une console qui reagit à ce que fait ta fenetre. Ici, je n'ai plus qu'un seul thread (le "principal") que je maintiens en vie avec le Application.Run(Form) (d'ailleurs si tu ne veux pas afficher la Form, tu utilises Application.Run(void), la form ne s'affichera pas du tout).

    Bon courage.

  10. #10
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    196
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 196
    Points : 94
    Points
    94
    Par défaut
    Merci de ton aide!!!
    Effectivement, avec Application.Run ça marche, j'intercepte les fermeture de sessions, les mises en veilles, changement d'utilisateur... Parcontre l'appel de Run avec void compile pas. Ca marche en faisant Application.Run((Form1)null) ou Application.Run() et j'en n'ai pas de Form qui s'affiche. Parcontre, je n'intercepte pas les messages comme la mise en veille.

    Comment puis-je resoudre le problème?
    Merci!!!!

  11. #11
    Rédacteur
    Avatar de Greybird
    Inscrit en
    Juin 2002
    Messages
    673
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 673
    Points : 1 271
    Points
    1 271
    Par défaut
    Bonjour,

    Si tu fais un service, pourquoi développes-tu une application console ?

    Quand tu développes un service en dérivant de ServiceBase, tu as déjà une méthode pour intercepter les évenements de session.

    Arnaud

  12. #12
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    196
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 196
    Points : 94
    Points
    94
    Par défaut
    Bonjour,
    Je ne me suis pas arreter sur ServiceBase parce qu'il y a des messages autres que les évènements de sessions que je dois intercepter (débranchement d'un cable réseau par exemple) et que dans la doc, j'ai pas vu grand chose qui m'y a fait penser... (je me trompe peut etre???)
    Je passe par une appli console pour test avant de modifier le code du service mais c'est juste pour mettre en place le méchanisme avant.

    Merci!!!

  13. #13
    Rédacteur
    Avatar de Greybird
    Inscrit en
    Juin 2002
    Messages
    673
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 673
    Points : 1 271
    Points
    1 271
    Par défaut
    Citation Envoyé par jesus144 Voir le message
    Bonjour,
    Je ne me suis pas arreter sur ServiceBase parce qu'il y a des messages autres que les évènements de sessions que je dois intercepter (débranchement d'un cable réseau par exemple) et que dans la doc, j'ai pas vu grand chose qui m'y a fait penser... (je me trompe peut etre???)
    Je passe par une appli console pour test avant de modifier le code du service mais c'est juste pour mettre en place le méchanisme avant.

    Merci!!!
    Effectivement, l'interception de messages Windows par les services est plutôt compliquée, potentiellement génératrice de failles de sécurité, et a priori impossible sous Vista d'après le MSDN.

  14. #14
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    196
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 196
    Points : 94
    Points
    94
    Par défaut
    J'avoue que sous vista ça risque de me poser des problèmes....
    Pour XP et précédents, coté sécurité, je pense que tu parles de tout ce qui est "shatter attack"... qui effectivement peuvent ammener des vulnérabilités.

    Ceci-dit, je ne vois pas comment faire autrement, l'idée de mon appli est de modifier des droits ou de chiffrer des fichiers en fonctions d'évènements. Par exemple, le débranchement du cable réseau entrainerai la fermeture de session, l'insertion d'une clé contenant certaines info permettrai de setter des droits sur des fichiers qui seraient restaurés à l'extraction de cette dernière...

    C'est pour cela que je cherche à traiter les messages Windows depuis un programme s'éxécutant en service. Je ne vois pas comment faire autrement compte tenu de la variété des évènements qui peuvent se produire.

    Pour l'aspect communication, je passe par des interfaces graphiques qui s'éxécutent depuis la session utilisateur et communiquent avec le service via des named pipes sur lesquels j'ai définis des droits. Ce qui limite la surface d'attaque sur le service...

    Merci de ton aide!!!

  15. #15
    Rédacteur
    Avatar de Greybird
    Inscrit en
    Juin 2002
    Messages
    673
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 673
    Points : 1 271
    Points
    1 271
    Par défaut
    Pour ce qui est de l'insertion d'une clé, si tu parles d'une clé USB, tu peux regarder du côté de RegisterDeviceNotification.
    Pour les histoires de réseau, si tu souhaites utiliser uniquement un service, je pense que le polling doit être la seule solution, à moins qu'il n'existe le même genre de notification côté réseau, mais je ne suis pas très calé là dessus.

    Bon courage en tout cas

    Arnaud

  16. #16
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    196
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 196
    Points : 94
    Points
    94
    Par défaut
    Merci pour le lien, je vais regarder .
    Parcontre pour l'aspect réseau, le polling ça m'a pas l'air tip top, vu qu'il y a une chtite icone qui notifie le débranchement du cable sous windows...

    Merci!!!

Discussions similaires

  1. ShellExecute dans une application console?
    Par balu dans le forum Delphi
    Réponses: 5
    Dernier message: 24/06/2006, 21h26
  2. [C#]Marquer une pause dans une application Console
    Par KibitO dans le forum Windows Forms
    Réponses: 2
    Dernier message: 14/06/2006, 16h28
  3. Les caractères dans une application console
    Par maximedrouet dans le forum Langage
    Réponses: 2
    Dernier message: 26/05/2005, 16h44
  4. Utiliser un timer dans une application console
    Par chavers dans le forum Langage
    Réponses: 8
    Dernier message: 25/05/2005, 14h07

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