2008-12-10 8 views
1

J'ai créé un service Windows qui utilise Windows Messaging System. Lorsque je teste l'application du débogueur les messages passent par bien mais quand je l'installe mon messag ... a demandé 14 minutes il y aTService ne traite pas les messages

vladimir 1tuga

+0

Exemple de code aiderait .... – CheGueVerra

+1

Il semble que vous n'avez pas fini de poser votre question. –

Répondre

5

Que voulez-vous dire quand vous dites « utilise » système Windows Messaging ? Consommez-vous ou envoyez-vous des messages Windows?

Si vous envoyez un message Windows, vous devez vous assurer que vous le faites correctement. Je suggère d'écrire une boucle de message pour assurer que vos messages sont expédiés correctement. Je suggère également de lire sur les boucles de messages et comment ils fonctionnent.

What is a Message Loop (cliquez sur le titre à prendre à la source de cette info)

while(GetMessage(&Msg, NULL, 0, 0) > 0) 
{ 
    TranslateMessage(&Msg); 
    DispatchMessage(&Msg); 
} 
  1. La boucle de message appelle GetMessage(), qui regarde dans la file d'attente de messages. Si la file d'attente de messages est vide, votre programme s'arrête et attend pour un (Blocs).
  2. Lorsqu'un événement a lieu provoquant un message devant être ajouté à la file d'attente (par exemple le système enregistre un clic de souris ) GetMessages() retourne une valeur positive indiquant qu'il ya un message à traiter, et qu'il a rempli les membres de la structure MSG nous l'avons adopté. Il renvoie 0 s'il atteint WM_QUIT et une valeur négative en cas d'erreur.
  3. Nous prenons le message (dans le Msg variable) et le transmettre à TranslateMessage(), cela fait un peu de traitement supplémentaire, traduire les messages clés virtuels dans des messages de caractère. Cette étape est en fait facultative, mais certaines choses ne fonctionneront pas si elle n'est pas là.
  4. Une fois cela fait, nous passons le message à DispatchMessage(). Qu'est-ce que DispatchMessage() est fait prendre le message , vérifie quelle fenêtre est et regarde ensuite la fenêtre Procédure de la fenêtre. Il a ensuite appelle cette procédure, l'envoi comme paramètres la poignée de la fenêtre, le message et wParam et lParam.
  5. Dans votre procédure de fenêtre vous vérifiez le message et ses paramètres, et faire tout ce que vous voulez avec eux! Si vous ne manipulez pas le message spécifique, vous appelez presque toujours DefWindowProc() qui effectuera les actions par défaut pour vous (ce qui signifie signifie souvent qu'il ne fait rien).
  6. Une fois que vous avez terminé le traitement le message, vos fenêtres procédure les retours, les retours DispatchMessage(), et nous allons revenir au début de la boucle .
+0

Bien que ce soit d'excellentes informations générales sur le traitement des messages dans Windows, il ne s'applique pas directement à Delphi où la boucle de message et même l'objet de message réel sont généralement cachés au développeur. –

+0

Que voulez-vous dire "caché"? Je peux traduire ce code exact en Delphi (et je l'ai fait dans les projets de production), et WHAM, j'ai une boucle de message. Ils sont simplement en dehors de l'API, que Delphi peut pleinement accéder et utiliser comme en C/C++ – Mick

+0

Vrai, vous pouvez le faire, mais je voulais dire que vous n'avez pas à le faire. Par exemple, je peux créer un nouveau projet avec un formulaire et configurer un gestionnaire pour un type de message particulier. Ensuite, sans aucune tentative de construction d'une boucle de traitement de message, mon gestionnaire recevra ces messages. –

7

services ne reçoivent généralement pas des messages de fenêtre. Ils n'ont pas nécessairement de poignées de fenêtre.Même s'ils le font, ils fonctionnent dans un bureau séparé. Les programmes ne peuvent pas envoyer de messages d'un bureau à un autre, de sorte qu'un service peut uniquement recevoir des messages d'un autre service ou d'un programme démarré par un service. Avant Windows Vista, vous pouviez configurer votre service pour interagir avec le bureau. Cela fait que le service s'exécute sur le même bureau que l'utilisateur connecté, de sorte qu'un programme s'exécutant en tant qu'utilisateur peut envoyer des messages aux fenêtres de votre service. Windows Vista isole les services, cependant; ils ne peuvent plus interagir avec le bureau d'un utilisateur.

Il existe de nombreuses autres façons de communiquer avec les services. Ils incluent les canaux nommés, les mailslots, les fichiers mappés en mémoire, les sémaphores, les événements et les sockets. Par exemple, avec un socket, votre service peut écouter sur un port ouvert, et les programmes qui doivent communiquer avec lui peuvent se connecter à ce port. Cela pourrait ouvrir la porte à l'administration à distance, mais vous pouvez également restreindre le service pour écouter uniquement les connexions locales.

Tout ce qui précède essaie de vous dire que vous prenez la mauvaise approche. Mais il y a aussi la question du problème. Votre programme se comporte d'une façon dans le débogueur et d'une autre manière en dehors de celui-ci. Comment déboguez-vous le service en premier lieu, s'il n'est pas installé? Quel compte d'utilisateur votre service fonctionne-t-il? Votre débogueur? Quelles techniques de débogage avez-vous essayées qui n'impliquent pas le débogueur (par exemple writeln dans un fichier journal pour suivre les actions de votre programme)?

+0

Services dans Delphi DO ont la capacité de recevoir des messages de fenêtre sans créer une pompe de message. Pour le prouver, créez un service dans Delphi, et vous remarquerez quelque chose qui crée un formulaire (par exemple une fenêtre 'cachée' comme une application VCL normale): Application.CreateForm (TMyService1, MyService1); – Mick

+1

Néanmoins, il ne peut pas recevoir de messages d'un programme exécuté dans un autre bureau. –

+0

Oui, c'est vrai dans Windows Vista. Cela est dû au fait que le service s'exécute avec des privilèges SYSTEM et que son processus a un niveau d'intégrité (IL) plus élevé qu'une application exécutée par l'utilisateur. Il est possible d'élever l'IL d'une application et d'envoyer des WM à un service. Mais ce n'est pas possible avec une application de production – Mick

0

Merci à tous pour les réponses, le problème était le système d'exploitation (Vista), j'ai testé le avec mon Windows 2000 et tout fonctionne.

merci pour la lumière Rob.

Questions connexes