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

Visual C++ Discussion :

Objet COM dans un service


Sujet :

Visual C++

  1. #1
    Membre éprouvé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Points : 937
    Points
    937
    Par défaut Objet COM dans un service
    Bonjour,

    J'essaie de créer un Service en C++ contenant des objets COM sous Visual Studio 2015 pro (et Windows 7).

    J'ai créé un projet ATL win32, sans MFC, sous forme de Service executable (pas DLL).
    Appelons-le MonServ.exe.
    J'ai ajouté un objet COM, un membre et une méthode pour essayer.
    J'ai ajouté un appel à CoInitializeSecurity(...) dans HRESULT CMonServModule::InitializeSecurity() comme unique tâche "TODO" suggérée par le wizard.
    Pas de soucis jusque là.
    (un détail curieux, le wizard a en fait créé deux projets, le deuxième étant une DLL avec le nom de mon executable suivi de PS en suffix, MonServPS.dll (PS comme Proxy/Stub ???), j'en fais quoi ?).

    J'ai ensuite créé un autre projet de test win32 console pour accéder à l'objet COM du premier.
    Et là, je ne parviens pas à accéder à l'objet COM du service lorsque celui-ci est enregistré comme tel par windows.

    Je m'explique.
    Je lance MonService.exe avec l'option -Service: il est enregistré comme service sous Windows, mais je ne parviens pas à communiquer avec lui depuis mon prg de test (le service est bien demarré, ou arrêté, ou en pause, rien n'y change).
    Je lance MonService.exe avec l'option -RegServer: là, Windows le retire de sa liste des services (grrr, pourquoi ???). Par conte mon prg de test accède alors bien à l'objet COM (et lance comme par magie MonService.exe que je vois apparaitre dans la liste des tâches, puis redisparait aussitôt lorsque mon prg de test se termine).

    En bref, j'ai un service, ou un objet COM accessible, mais pas les deux en même temps, et je ne comprends pas ce qui manque pour cela. Le tout étant créé entièrement par les wizard de Visual Studio 2015.

    Merci pour votre aide.

  2. #2
    Membre éprouvé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Points : 937
    Points
    937
    Par défaut
    Petite info supplémentaire, j'ai débuggé et dans le code atlbase.h l'appel à CoCreateInstance() renvoit le code HRESULT = 0x80080005.
    Le message associé est "Server execution failed".

  3. #3
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    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 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Franchement je ne suis pas très au fait des (in)compatibilités entre les Services Windows et les serveurs DCOM (tout ce que je sais, c'est que les second sont lancés par un des premiers, le "Lanceur de processus serveur DCOM", alias DcomLaunch).

    Mais il y a fort à parier que DcomLaunch ne sait pas que ton programme doit être lancé via StartService() plutôt que CreateProcess(). Est-ce qu'il existe un moyen de le configurer de la sorte, je l'ignore; mais tant que DcomLaunch lancera ton programme "normalement", l'appel à StartServiceCtrlDispatcher() échouera avec ERROR_FAILED_SERVICE_CONTROLLER_CONNECT.

    PS: MonServerPS.dll est bien le Proxy/Stub servant à marshaller les appels inter-processus pour toute interface que tu définis dans ton projet; tu es censé l'enregistrer au même titre que le service, si Visual Studio ne le fait pas tout seul au build.

    Toutefois, cette DLL sera superflue si toutes tes interfaces sont Automation-compatibles et marquées oleautomation, auquel cas le marshaling se fera via le OLE Automation Marshaler à la place, qui a seulement besoin d'avoir la Type Library contenant tes interfaces à portée de main.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  4. #4
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    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 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Je ne trouve pas d'information sur comment configurer un composant DCOM pour que le lanceur le démarre comme service.

    Par contre, si tu es prêt à ce que le service tourne H24 plutôt que à la demande (et d'ailleurs, j'ai du mal à voir d'autre raison pour laquelle tu voudrais spécifiquement que le composant soit un service), tu pourrais probablement t'affranchir complètement de DcomLaunch (en ne remplissant pas la clé LocalServer32 peut-être?): Lancer simplement le service en "Automatique" (potentiellement différé pour éviter de surcharger le démarrage) et laisser COM le trouver dynamiquement...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 069
    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 069
    Points : 12 113
    Points
    12 113
    Par défaut
    Je ne suis pas sûr qu'une approche Service Windows comme host d'un composant COM soit le genre de truc fiable dans des environnements multi-sessions (Terminal Server du bon vieux temps).

    Pourquoi le composant en Service et pas dans une Dll dédiées, qui pourrait ensuite communiquer avec le service via autre chose que COM ?

  6. #6
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 069
    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 069
    Points : 12 113
    Points
    12 113
    Par défaut
    Je ne suis pas sûr qu'une approche Service Windows comme host d'un composant COM soit le genre de truc fiable dans des environnements multi-sessions (Terminal Server du bon vieux temps).

    Pourquoi le composant en Service et pas dans une Dll dédiées, qui pourrait ensuite communiquer avec le service via autre chose que COM ?

  7. #7
    Membre éprouvé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Points : 937
    Points
    937
    Par défaut
    Médinoc, merci pour ta réponse.
    Je pense que tu as compris le contraire de ce que j'exprime

    Je souhaite comme tu le dis que le service tourne 24/24h, mais c'est justement dans ce cas que l'objet COM n'est pas trouvé (dynamiquement ?).

    L'objet COM est par contre bien trouvé en "Local Server", quand l'EXE est chargé à la demande (ce qui ne m'aide pas, autant faire une DLL).

    J'ai trouvé une page chez MS qui explique le déroulement de création d'un service avec objet ATL COM, et où on explique que lors du développement et pour faciliter le debugging l'objet est enregistré en "local server".
    Ensuite, rien n'empêche en production d'enregistrer le service en tant que tel en fin de compte.
    https://msdn.microsoft.com/en-us/library/74y2334x.aspx
    Mais je n'y trouve aucune explication au fait que cela puisse ne pas fonctionner en service

    Je pense que le soucis est une question de droit d'utilisateur.
    J'ai essayé de faire plusieurs changements, autant dans les paramètres du service que dans la config DCOM, sans succès...

    Toute aide supplémentaire est bienvenue.

  8. #8
    Membre éprouvé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Points : 937
    Points
    937
    Par défaut
    Barcelar,
    Je souhaite un service car je ne connais pas d'autre moyen d'avoir un prg qui tourne tout le temps, le but étant de précharger en mémoire des données afin de ne pas perdre ce précieux temps à chaque accès.
    Les DLL ne sont chargées qu'à la demande, et leur espace mémoire est le même que celui du process les appelant (enfin, je crois...). Je me dis qu'avec un service la gestion de mémoire sera sans doute meilleure.

    Ceci étant, je récupère un projet d'il y a 15 ans écrit sous Visual Studio 6.
    Visual Studio 6 ne tourne plus sur les OS plus récents que XP. Des soucis de maintenance commence à se poser...
    Je transfère le tout sous VS2015 mais je dois conserver la compatibilté d'usage, c-à-d la communication COM (script en VB, JS, ASP, etc...).
    C'est une DLL, mais je voulais en faire un service pour éviter les initialisations récurrentes.

    J'utilise toujours ceci en COM:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    #import <C:\Program Files\Common Files\SYSTEM\ADO\msado60.tlb> named_guids rename("EOF", "EndOfFile")
    #import <msxml6.dll> named_guids
    S'il y a mieux aujourd'hui, je suis preneur (c'est vrai que c'est vieux COM).

  9. #9
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    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 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Pour voir si c'est un problème de sécurité, essaie en assignant au service le même utilisateur que celui qui tente de contacter l'objet.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  10. #10
    Membre éprouvé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Points : 937
    Points
    937
    Par défaut
    Ouf !
    J'ai trouvé

    J'avais essayé de chipoter avec les droits d'accès au service, rien n'y faisait...

    Voici la page avec la solution:
    https://connect.microsoft.com/Visual...ing-components
    Si j'ai bien compris, c'est un bug dans le ATL COM wizard de Visual Studio 2012. Et il est toujours présent dans Visual Studio 2015
    Les fichiers .rgs autogénérés sont incomplets.
    J'ai donc completé à la main les .rgs, et ça marrrche

  11. #11
    Membre éprouvé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Points : 937
    Points
    937
    Par défaut
    Et, accessoirement, google me gonfle.
    La page précitée n'apparait pas dans les premières réponses avec la recherche de "0x80080005 Server execution failed"

    EDIT: et encore un lien chez microsoft avec l'explication:
    https://blogs.msdn.microsoft.com/jig...d-atl-service/
    Pratiquement introuvable avec google...

    Je me demande si je ne vais pas commencer à utiliser bing pour ce genre de recherche

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

Discussions similaires

  1. Objet COM dans un executable
    Par Flow_75 dans le forum Windows
    Réponses: 4
    Dernier message: 15/12/2014, 11h14
  2. charger objet Com dans une page web
    Par psycho_xn dans le forum Général Dotnet
    Réponses: 18
    Dernier message: 12/11/2009, 17h55
  3. Réponses: 1
    Dernier message: 17/04/2009, 17h56
  4. [POO] débutante dans les objets COM
    Par SandraG dans le forum Langage
    Réponses: 11
    Dernier message: 16/03/2006, 12h03
  5. Mettre un objet utilisant COM dans un vecteur
    Par 0xYg3n3 dans le forum MFC
    Réponses: 7
    Dernier message: 18/04/2005, 15h50

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