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

Windows Discussion :

VC++/WXP et messages d'un service


Sujet :

Windows

  1. #1
    Membre régulier Avatar de Joccy
    Profil pro
    Inscrit en
    Août 2007
    Messages
    153
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 153
    Points : 81
    Points
    81
    Par défaut VC++/WXP et messages d'un service
    Bonjour,

    J'ai un service perso qui tourne: il interroge régulièrement le materiel pour savoir s'il est en mode batterie ou en mode secteur.

    Je dois faire une API qui interroge ce service. Bon, jusque là ca va (enfin je crois) .

    Maintenant, je dois recupérer des valeurs, via un echange de message je suppose (si autre méthode, je prends).
    Comment récupérer des valeurs ?
    Procédure : (??)
    - Le client demande à mon API le type d'alimentation: j'envoie un PostMessage() au service.
    Comment faire pour récupérer la valeur du type d'alim ?
    - Je suppose que le service va renvoyer un PostMessage à ma dll (API) avec la valeur dedans. Comment intercepter ce message ? ma dll n'a pas de fenetre, donc pas de possibilité d'utiliser defwindowproc() ... Est-ce dans un hook que je dois intercepter ces messages ? ou dans un thread ???
    Merci de vos conseils

  2. #2
    Membre habitué
    Homme Profil pro
    Inscrit en
    Septembre 2007
    Messages
    109
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 109
    Points : 168
    Points
    168
    Par défaut
    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
    #include <windows.h>
    #include <stdio.h>
    #include <conio.h>
    
    int main(void)
    {
      SYSTEM_POWER_STATUS sps;
    
      while(!kbhit())
      {
        if(GetSystemPowerStatus(&sps))
        {
          printf("%s\r", sps.ACLineStatus == 0 && sps.BatteryLifePercent != 255 ? "Batterie" : "Secteur ");
          Sleep(500);
        }
        else
        {
          printf("Echec ! (0x%08lX)\n", GetLastError());
          break;
        }
      }
    
      return 0;
    }

  3. #3
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 379
    Points : 41 573
    Points
    41 573
    Par défaut
    Pour communiquer avec un service, une méthode souvent conseillée est le tube nommé (named pipe).

    Sinon, pour un truc simple, tu peux toujours utiliser SendMessage(), qui est synchrone et attend une valeur de retour.

  4. #4
    Expert éminent sénior
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 386
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 386
    Points : 20 466
    Points
    20 466
    Par défaut
    Oui je crois que la solution la meilleure c'est de faire un process intercommunication un "pipe" comme le dit Médinoc..

  5. #5
    Membre régulier Avatar de Joccy
    Profil pro
    Inscrit en
    Août 2007
    Messages
    153
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 153
    Points : 81
    Points
    81
    Par défaut
    J'opte pour les pipes, en plus ce sera plus portable ( à terme, faudra que je me mette à linux, alors !!).
    Bon, j'essaye et je vous tiens au courant.
    Merci

    PS: pour magma2 : c'est gentil de ton aide, mais en fait, le systeme de batterie est géré différemment (c'est un pc "fait maison" ...)

  6. #6
    Membre régulier Avatar de Joccy
    Profil pro
    Inscrit en
    Août 2007
    Messages
    153
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 153
    Points : 81
    Points
    81
    Par défaut
    Bon, autre question : est-ce que le service (celui qui ecrit les datas) doit toujours être à l'ecoute de la demande ? Parce que ca, ca m'embete ...
    Comment faire pour que le service ne reponde que lorsqu'on lui demande ?

    PS: je suis allée sur le site suivant http://somebastardstolemyname.wordpr...c-named-pipes/

  7. #7
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 153
    Points : 12 264
    Points
    12 264
    Par défaut
    Où est le problème ?
    C'est une attente bloquante, donc n'utilisant aucune cible CPU?

  8. #8
    Membre régulier Avatar de Joccy
    Profil pro
    Inscrit en
    Août 2007
    Messages
    153
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 153
    Points : 81
    Points
    81
    Par défaut
    Bon, j'chuis perdue ....

    Voila mon "serveur":
    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
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    BOOL CMaClasse::getTypeAlim (BOOL *p_bSect)
    {
    	BOOL bRet = TRUE;
    
    	// si pas de service MonService, quitter
    	if (! m_bConnected) 
    	{
    		m_dwLastError = ERROR_OPERATION_ABORTED;
    		return FALSE;
    	}
    
    	// Creation d'un pipe pour communiquer avec le service MonService
    	LPCTSTR _PIPE_NAME = LPCTSTR("\\\\.\\pipe\\MonServicePipe");
    	char Received_Buffer[256];
    	DWORD BytesRead = 0;
    
    	HANDLE hPIPE = CreateNamedPipe(		_PIPE_NAME,
    										PIPE_ACCESS_DUPLEX, 
                                            PIPE_TYPE_MESSAGE |  
                                            PIPE_READMODE_MESSAGE | 
                                            PIPE_WAIT, 
                                            PIPE_UNLIMITED_INSTANCES,  
                                            256, 
                                            256, 
                                            10000, //100 00 mseconds timeout
                                            0x00000000					);
    	
    	DWORD l_dwControl;
    
    	// envoie de l'evenement pour indiquer à MonService la demande
    	l_dwControl = MONSERVICE_CMD_QUERY_TYPE_ALIM;
    
    	if (m_bSecured) {
    		if (! ControlService(m_hService, l_dwControl, &m_ServiceStatus)) 
    		{
    			m_dwLastError = GetLastError();
    			bRet = FALSE;
    		}
    	}
    	else {
    		if (! PostMessage(m_hWnd, MONSERVICESIG_SERVICE_CONTROL, l_dwControl, 0)) 
    		{
    			m_dwLastError = GetLastError();
    			bRet = FALSE;
    		}
    	}
    
    	// Attendre que le postmessage soit passé
    	//Sleep(1000);
    
    	// lire la réponse
    	if ( hPIPE != INVALID_HANDLE_VALUE && bRet == TRUE)
    	{
    		int Connected = 0;
    		Connected = ConnectNamedPipe( hPIPE, NULL );
    		m_dwLastError = GetLastError();
    
    		if ( (Connected != 0) || (m_dwLastError == ERROR_PIPE_CONNECTED))
    		{
    			BOOL bRead = ReadFile(hPIPE, Received_Buffer, 256, &BytesRead, NULL ); 
    
    			if ( bRead != 0 )
    			{
    //				MessageBox( NULL, Received_Buffer, "Recieved Text!", MB_OK );
    				m_iTypeAlim = atoi(Received_Buffer);
    			}
    		}
    		else
    		{
    //			MessageBox( NULL,"ConnectedNamePipe() Failed.", "Error!", MB_OK );
    			bRet = FALSE;
    		}
    	}
    	else
    	{
    //		MessageBox( NULL, " SERVER FAILED ON CreateNamedPipe()", "ERROR!", MB_OK );
    		bRet = FALSE;
    	}
    
    	DisconnectNamedPipe(hPIPE); 
    	CloseHandle(hPIPE);
     
    	*p_bSect = m_iTypeAlim;
        return bRet;
    }
    Voila mon "client" (qui fonctionne, avec les traces c'est OK):
    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
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    void CMainFrame::OnServiceEvent (UINT p_uiEvent, LPARAM p_lParam)
    {
        HWND hWnd = (HWND)p_lParam;
    	CString FileCmd;
        DWORD   ProcessExitCode = 0;
    
    
    	switch (p_uiEvent) 
    	{
    		// envoi du type d'alimentation (pour demande de l'API CMo)
    		case MONSERVICE_CMD_QUERY_TYPE_ALIM:
    			{
    				// TODO
    				trace_("CMainFrame::OnServiceEvent : MONSERVICE_CMD_QUERY_TYPE_ALIM");
    				LPCTSTR _PIPE_NAME = _TEXT("\\\\.\\pipe\\VisuSBPipeTypeALim");
    
    				HANDLE hPIPE = CreateFile(_PIPE_NAME, GENERIC_WRITE,0, NULL, OPEN_EXISTING,0, NULL);
    				char buffer[256];
    
    				//copy string into buffer and fill with terminating null characters
    				if ( hPIPE != INVALID_HANDLE_VALUE )
    				{
    					//Write char array "buffer" to the pipe handle held in hPIPE
    					bWrite = WriteFile( hPIPE, buffer, sizeof(buffer), &BYTESWRITTEN, NULL );
    					if ( bWrite == FALSE )
    					{
    						trace_("CMainFrame::OnServiceEvent : cannot write on pipe");
    					}
    					else
    					{
    						sprintf(buffer, "CMainFrame::OnServiceEvent : Write on pipe OK : %d", m_TypeAlim); 
    						trace_(buffer);					}
    				}
    				else 
    				{
    					trace_("CMainFrame::OnServiceEvent : cannot create file for pipe : Invalid pipe handle");
    				}
    
    				CloseHandle(hPIPE);
    			}
    			break;
    		default:
    			break;
    	}
    
    }
    MAIS, lorsque je récupère ma valeur, le "serveur"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Connected = ConnectNamedPipe( hPIPE, NULL );
    me renvoie l'erreur 232, c'est-à-dire "The pipe is being closed"

    Ou est donc le problème ?
    Merci de votre aide ...

  9. #9
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 153
    Points : 12 264
    Points
    12 264
    Par défaut
    Pourquoi "_PIPE_NAME" est différent entre le client et le serveur ?

  10. #10
    Membre régulier Avatar de Joccy
    Profil pro
    Inscrit en
    Août 2007
    Messages
    153
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 153
    Points : 81
    Points
    81
    Par défaut
    C'est une erreur en recopiant sur le forum. J'ai vérifié, ils ont bien le meme nom. Désolée.

  11. #11
    Membre régulier Avatar de Joccy
    Profil pro
    Inscrit en
    Août 2007
    Messages
    153
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 153
    Points : 81
    Points
    81
    Par défaut
    Bon. J'ai une petite précision à ajouter :
    * en débug (sans débugguer) ca fonctionne.
    * en Release j'ai l'erreur 0 (le connect renvoie 0, et le last error aussi je suppose)
    * en debugguant, j'ai l'erreur 232 ...
    Il s'agit sans doute d'un probleme de synchronisation ???

    Une idée ?
    Merci

  12. #12
    Membre régulier Avatar de Joccy
    Profil pro
    Inscrit en
    Août 2007
    Messages
    153
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 153
    Points : 81
    Points
    81
    Par défaut
    Encore une précision:
    en release, le fonction suivante
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    HANDLE hPIPE = CreateNamedPipe(		_PIPE_NAME,
    										PIPE_ACCESS_DUPLEX, 
                                            PIPE_TYPE_MESSAGE |  
                                            PIPE_READMODE_MESSAGE | 
                                            PIPE_WAIT, 
                                            PIPE_UNLIMITED_INSTANCES,  
                                            256, 
                                            256, 
                                            10000, //100 00 mseconds timeout
                                            0x00000000 //PIPE_ACCEPT_REMOTE_CLIENTS
    								);
    me renvoie un INVALID_HANDLE_VALUE ... et une erreur 183 "Cannot create a file when that file already exists".

    Alors que ca fonctionne en debug ....
    Helppppp !!

  13. #13
    Membre régulier Avatar de Joccy
    Profil pro
    Inscrit en
    Août 2007
    Messages
    153
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 153
    Points : 81
    Points
    81
    Par défaut
    Je précise que je suis sous Windows XP ... et VisualStudio VC++ 6.0 ..

  14. #14
    Membre régulier Avatar de Joccy
    Profil pro
    Inscrit en
    Août 2007
    Messages
    153
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 153
    Points : 81
    Points
    81
    Par défaut
    Bon voici la solution:
    Ne fonctionne pas:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    LPCTSTR _PIPE_NAME = LPCTSTR ("\\\\.\\pipe\\VisuSBPipeTypeALim");
    Fonctionne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    LPCTSTR _PIPE_NAME = _T("\\\\.\\pipe\\VisuSBPipeTypeALim");
    En incluant le fichier "tchar.h" de windows ....

  15. #15
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 379
    Points : 41 573
    Points
    41 573
    Par défaut
    C'est normal. Le premier code est l'équivalent d'un cast C-style déguisé...

  16. #16
    Membre régulier Avatar de Joccy
    Profil pro
    Inscrit en
    Août 2007
    Messages
    153
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 153
    Points : 81
    Points
    81
    Par défaut
    et pourquoi personne ne me l'a dit ???
    enfin, du moment que ca fonctionne ....

  17. #17
    Membre habitué Avatar de r2d2abc
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    212
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 212
    Points : 179
    Points
    179
    Par défaut
    Salut Joccy, je crois déjà que je mettrais le DisconnectNamedPipe & CloseHandle uniquement si le ConnectNamedPipe est bon et pas en bas du bloc en sortant (c.a.d ds le bloc if connected !=0
    Après le connected serait un bool pas un int (là je chipotte)
    je filerai le même pipename aux deux (déjà énoncé je crois)
    La variable buffer n'a pas l'air initialisée,
    Je ne mettrai pas un sizeof mais plutot un strlen(buffer)

    après on verra ..
    bon courage

  18. #18
    Membre régulier Avatar de Joccy
    Profil pro
    Inscrit en
    Août 2007
    Messages
    153
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 153
    Points : 81
    Points
    81
    Par défaut
    Merci de ton aide.
    En fait parfois tu reçois un "ERROR_PIPE_CONNECTED" alors que ca fonctionne ... C'est pourquoi je disconnecte et ferme le handle en dernier pour les deux cas (et que c'est un int)... Mais je vais regarder mon code plus attentivement encore et voir si je peux affiner.

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

Discussions similaires

  1. Pompe à messages dans un service
    Par engi dans le forum C++Builder
    Réponses: 6
    Dernier message: 14/05/2013, 13h56
  2. Réponses: 1
    Dernier message: 27/04/2012, 05h43
  3. Message erreur démarrage service Tomcat au démarrage
    Par juju05 dans le forum Tomcat et TomEE
    Réponses: 1
    Dernier message: 23/06/2010, 09h41
  4. Comment récupérer les windows message dans un service
    Par coxman68 dans le forum Débuter
    Réponses: 0
    Dernier message: 26/02/2009, 12h20
  5. Message box sous service web
    Par nemya dans le forum Services Web
    Réponses: 2
    Dernier message: 13/03/2008, 12h01

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