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++Builder Discussion :

Communication entre fenêtre et service


Sujet :

C++Builder

  1. #1
    Membre éclairé Avatar de benj63
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Mai 2002
    Messages
    207
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Responsable de service informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 207
    Par défaut Communication entre fenêtre et service
    Bonjour,

    Je cherche à faire transmettre des messages entre un exécutable (qui contient une Form) et un service. Le service envoie des informations (un log de fonctionnement) dans une zone mémoire, qui est lue à une fréquence régulière par mon exécutable, et qui affiche dans une listbox de la Form, les logs envoyés par le service.

    Voilà comment j'ai procédé :

    En commun entre mon service et mon exécutable :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    // Log en mémoire pour affichage lorsque le Service doit envoyer à la fenêtre le log
    typedef struct
    {
            bool CalculEnCours;
            bool DownloadEnCours;
            char texte[100][1000];  // [100] = on conserve jusqu'à 100 lignes en mémoire tampon ; [1000] = nombre de caractères maximum d'un message
    }FluxConteneur;
    HANDLE FluxCommun;
    Dans mon service :
    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
    // Ouverture de l'espace commun en mémoire entre ce service et l'IHM pour le partage du log
    FluxCommun = CreateFileMapping((HANDLE)0xFFFFFFFF, NULL, PAGE_READWRITE, 0, sizeof(FluxConteneur), "MonFluxCommun");
    if(FluxCommun==0)
    {
            FluxConteneur *data = (FluxConteneur *)MapViewOfFile(FluxCommun, FILE_MAP_ALL_ACCESS, 0, 0, 0);
            data->CalculEnCours = false;
            data->DownloadEnCours = false;
            UnmapViewOfFile(data);
    }
    else if (GetLastError() == ERROR_ALREADY_EXISTS)
    {
            CloseHandle(FluxCommun);
            FluxCommun = OpenFileMapping(FILE_MAP_ALL_ACCESS, false, "MonFluxCommun");
    }
     
    // Au moment de l'écriture d'une nouvelle ligne de log, paramètre "ligne" :
    if(FluxCommun!=NULL)
    {
            int i;
            FluxConteneur *data = (FluxConteneur *)MapViewOfFile(FluxCommun, FILE_MAP_ALL_ACCESS, 0, 0, 0);
     
            for(i=0;i<100;++i)
            {
                    if(strcmp(data->texte[i], "")==0)
                    {
                            strcpy(data->texte[i], ligne.c_str());
                            i = 99999;
                    }
            }
            if(i!=100000)
                    strcpy(data->texte[99], ligne.c_str());
     
            UnmapViewOfFile(data);
    }
    Dans mon exécutable, au démarrage, initialisation du flux commun :
    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
    // Ouverture de l'espace commun en mémoire entre le service et cette IHM pour le partage du log
    FluxCommun = CreateFileMapping((HANDLE)0xFFFFFFFF, NULL, PAGE_READWRITE, 0, sizeof(FluxConteneur), "MonFluxCommun");
    if(FluxCommun==0)
    {
            FluxConteneur *data = (FluxConteneur *)MapViewOfFile(FluxCommun, FILE_MAP_ALL_ACCESS, 0, 0, 0);
            data->CalculEnCours = false;
            data->DownloadEnCours = false;
            UnmapViewOfFile(data);
    }
    else
            if (GetLastError() == ERROR_ALREADY_EXISTS)
            {
                    CloseHandle(FluxCommun);
                    FluxCommun = OpenFileMapping(FILE_MAP_ALL_ACCESS, false, "MonFluxCommun");
            }
    Dans mon exécutable, pour l'actualisation de l'affichage dans une ListBox de ma Form, dans un OnTimer :
    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
    // Affichage du log
    if(FluxCommun!=NULL)
    {
            FluxConteneur *data = (FluxConteneur *)MapViewOfFile(FluxCommun, FILE_MAP_ALL_ACCESS, 0, 0, 0);
            calcul_en_cours = data->CalculEnCours;
            download_en_cours = data->DownloadEnCours;
            for(i=0;i<100;++i)
            {
                    if(strcmp(data->texte[i], "")!=0)
                    {
                            ListBox1->Items->Add(data->texte[i]);
                            ListBox1->ItemIndex = ListBox1->Items->Count-1;
                            Application->ProcessMessages();
                            strcpy(data->texte[i], "");
                    }
            }
            UnmapViewOfFile(data);
    }
    Cela fonctionne parfaitement sur mon ordinateur sous Windows XP... Mais quand je bascule tout cela sur un ordinateur équipé de Windows Server 2008, cela ne fonctionne plus, plus rien n'apparaît dans ma ListBox de ma Form, même si je coche dans les options du service "autoriser à intéragir avec le bureau" ou que je le fais démarrer en tant qu'utilisateur "administrateur"...

    Merci par avance pour votre aide !

  2. #2
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 081
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 081
    Par défaut
    2008 R1 ? R2 ?
    Sinon, pourquoi ne pas créer ton journal système avec TService.LogMessage

    En général, je préfère le TCP\IP dans un Service, cela permet de monitorer celui-ci d'un autre poste, utile lorsque la salle des serveurs est difficilement accessible (sécurité, congelo...)

    J'ai aussi jouer avec CreateFileMapping, mais j'ai ajouté un Event nommé pour que la lecture soit faite que lorsque cela est utile, au lieu d'un TTimer

    Pense à définir une session à ton service, n'utilise pas SYSTEM mais un compte dédié avec tous les droits nécessaires,

    Code CMD : Sélectionner tout - Visualiser dans une fenêtre à part
    sc.exe config ServiceName obj=... password=...
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  3. #3
    Membre éclairé Avatar de benj63
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Mai 2002
    Messages
    207
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Responsable de service informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 207
    Par défaut
    Merci pour ta réponse.

    Il s'agit de Windows Server 2008 Standard, Service Pack 2.

    Je n'utilise pas de journal système (avec TService.LogMessage par exemple) car en + d'un log, je transmets d'autres infos via mon FluxConteneur (un booléen qui indique si un calcul ou un téléchargement est en cours, qui s'affichent sous forme de petites icônes d'état dans ma fenêtre principale).

    Je vais essayer d'utiliser un compte au lieu de system et voir ce que ça donne...

  4. #4
    Membre éclairé Avatar de benj63
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Mai 2002
    Messages
    207
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Responsable de service informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 207
    Par défaut
    J'ai tenté :
    sc config MonService obj= Administrateur password= ******
    qui me retourne :
    [SC] ChangeServiceConfig échec(s) 1057 :

    Le nom de compte n'est pas valide ou n'existe pas, ou le mot de passe n'est pas valide pour le nom de compte spécifié.
    Pourtant c'est bien le compte avec lequel je me suis connecté... On n'a pas le droit d'utiliser le compte Administrateur ?...

  5. #5
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 081
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 081
    Par défaut
    Tu as mis l'espace entre obj= et Administrateuril ne faut pas, ni après password=
    Windows Server 2008 Standard, Service Pack 2
    semble que cela soit du R1, je suppose un 32Bits ?
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  6. #6
    Membre éclairé Avatar de benj63
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Mai 2002
    Messages
    207
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Responsable de service informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 207
    Par défaut
    Il s'agit effectivement d'un Windows Server 32 bits.

    Sans espace c'est pire en fait :
    sc config UAS_Service obj=Administrateur password=*****
    fs
    DESCRIPTION :
    Modifie l'entrée d'un service dans le Registre et la base de données
    des services.
    UTILISATION :
    sc <serveur> config [nom service] <option1> <option2>...

    OPTIONS :
    REMARQUE : le nom d'option contient le signe égal.
    Un espace est nécessaire entre le signe égal et la valeur. type= <own|share|interact|kernel|filesys|rec|adapt>
    start= <boot|system|auto|demand|disabled|delayed-auto>
    error= <normal|severe|critical|ignore>
    binPath= <NomCheminBinaire>
    group= <GroupeOrdreChargement>
    tag= <yes|no>
    depend= <Dépendances (séparées par / (barre oblique))>
    obj= <NomCompte|NomObjet>
    DisplayName= <nom complet>
    password= <mot de passe>

  7. #7
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 081
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 081
    Par défaut
    Citation Envoyé par benj63 Voir le message
    Sans espace c'est pire en fait :
    Mince, ça fait 3 ans que je l'ai pas fait, du coup j'oublie les astuces de ce genre

    Depuis XP, ils ont amélioré la doc !

    ...
    sc <server> config [service name] <option1> <option2>...
    CONFIG OPTIONS:
    NOTE: The option name includes the equal sign.
    type= <own|share|interact|kernel|filesys|rec|adapt>
    ...
    Alors, c'est que ton compte administrateur n'a pas le droit d'être utilisé pour démarrer un service, faudrait voir avec ton admin justement

    Moi, j'utilisais soit mon propre compte pour le dev et un compte dédié crée par mon admin réseau avec les droits de lancer des applis et tout plein de truc mais pas un admin !
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  8. #8
    Membre éclairé Avatar de benj63
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Mai 2002
    Messages
    207
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Responsable de service informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 207
    Par défaut
    Je suis toujours avec mon problème...

    Je me dis que ce que tu as fait :
    Citation Envoyé par ShaiLeTroll Voir le message
    J'ai aussi jouer avec CreateFileMapping, mais j'ai ajouté un Event nommé pour que la lecture soit faite que lorsque cela est utile, au lieu d'un TTimer
    serait déjà + propre que d'utiliser un TTimer !

    Pourrais-tu m'indiquer comment créer un Event dans le service et le récupérer dans mon appli principale ?

    Merci par avance !

  9. #9
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 081
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 081
    Par défaut
    Soit API CreateEvent, le paramètre lpName donne le nom qui permet à plusieurs processus de partager le même objet

    le TEvent de la VCL encapsule cela et il faut bien spécifier Name, je ne l'ai pas encore essayé mais TMutex qui fonctionne globalement de la même façon pour le nommage lui fonctionne parfaitement !
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  10. #10
    Membre éclairé Avatar de benj63
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Mai 2002
    Messages
    207
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Responsable de service informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 207
    Par défaut
    J'ai trouvé une réponse à mon problème pour utiliser CreateFileMapping dans mon service !

    Il faut débuter le nom de l'espace mémoire en commun par "Global\\" car les services ne fonctionnent pas sur le même namespace que les sessions utilisateurs (si j'ai bien compris). Voilà notamment une personne qui rencontrait le même problème que moi :
    http://go4answers.webhost4life.com/E...ows-53450.aspx

    Bref, j'ai changé dans mon code "MonFluxCommun" par "Global\\MonFluxCommun" et cela fonctionne (et je n'ai pas eu besoin de changer les droits de mon service pour qu'il fonctionne sur un compte dédié)

    Merci en tout cas d'avoir participé à tout cela ShaiLeTroll

  11. #11
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 081
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 081
    Par défaut
    Eh bien, c'est une information intéressante !
    Cela me servira peut-être un jour

    CreateFileMapping je ne l'ai utilisé qu'en deux instances d'un même objet OLE l'un lancé par Delphi et l'autre par un script PHP mais pas en service !
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

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

Discussions similaires

  1. Problème de communication entre fenêtres
    Par rvbp13 dans le forum Qt
    Réponses: 1
    Dernier message: 30/06/2010, 15h01
  2. Communication entre fenêtres ?
    Par jacpapac dans le forum Windows Presentation Foundation
    Réponses: 3
    Dernier message: 12/05/2009, 09h47
  3. Communication entre fenêtres : passage de valeurs
    Par Bleys dans le forum Débuter
    Réponses: 11
    Dernier message: 16/06/2008, 20h39
  4. Réponses: 2
    Dernier message: 31/01/2008, 09h46
  5. Communication entre fenêtres avec windows
    Par zabibof dans le forum Bibliothèques
    Réponses: 5
    Dernier message: 02/04/2007, 10h52

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