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 :

Lancement d'un composante dans un service (VS2010, C++)


Sujet :

Visual C++

  1. #1
    Membre du Club
    Inscrit en
    F�vrier 2011
    Messages
    6
    D�tails du profil
    Informations forums :
    Inscription : F�vrier 2011
    Messages : 6
    Par d�faut Lancement d'un composante dans un service (VS2010, C++)
    Bonjour,
    je travaille avec VS2010 en C++
    je tente de convertir un logiciel qui fonctionne avec des composantes en un programme de service. (background)
    Conform�ment � l'exemple de code, le service CMyService d�marre correctement si je mets le 1er return avant le CoCreateInstance(..) et ne d�marre pas (TimeOut) avec le 2eme return apr�s le CoCreateInstance().
    Il y a donc un probl�me avec le CoCreateInstance().
    Lequel?
    Merci pour tous les conseils et r�ponses.
    Bernard

    exemple:
    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
     
    bool CMyService::OnInit(void)
    {
    	return CreateListObject();
    }
     
    bool CMyService::CreateListObject()
    {
    //    return false;
     
    	HRESULT hr = ::CoCreateInstance(CLSID_CListObject,
                                        NULL,
                                        CLSCTX_INPROC_SERVER,
                                        IID_IUnknown,
                                        (LPVOID*)&m_pListObjet);
        return true;
     
     
        if (FAILED(hr)) {
    	    // appliances n'est plus a jour : rebuild all // pbm de appliances.reg (x86-d, x86-r)
             TRACE("Failed to create object. SCODE: %8.8lXH (%lu)\n",
                 GetScode(hr),   GetScode(hr) & 0x0000FFFF);
            m_pListObjet = NULL;
            return false;
        }
        ASSERT(m_pListObjet);
        ...
    }

  2. #2
    Expert confirm�
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    F�vrier 2005
    Messages
    5 503
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 53
    Localisation : France, Val de Marne (�le de France)

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

    Informations forums :
    Inscription : F�vrier 2005
    Messages : 5 503
    Par d�faut
    Dans quel type de thread essayez-vous de faire CoCreateInstance ?
    Quel est le type d'appartment du composant que vous voulez instancier ?
    Avez-vous d�j� appel� CoInitialize dans ce thread ? Si oui, avec des options compatibles avec l'appartment du composant ?

  3. #3
    Membre du Club
    Inscrit en
    F�vrier 2011
    Messages
    6
    D�tails du profil
    Informations forums :
    Inscription : F�vrier 2011
    Messages : 6
    Par d�faut re
    Dans quel type de thread essayez-vous de faire CoCreateInstance ?
    1 seul service et 1 seul thread. non?
    Quel est le type d'appartment du composant que vous voulez instancier ?
    CLSCTX_INPROC_SERVER pas aggrege (ca marche ds le pgm source)
    Avez-vous d�j� appel� CoInitialize dans ce thread ? Si oui, avec des options compatibles avec l'appartment du composant ?[/QUOTE]

    il n'y a pas de template de projet service ds VS2010. J'utilise une base a partir de http://www.codeproject.com/Articles/...d-Line-Service
    le CoCreateInstance marche (return S_OK) mais m_pListObjet reste NULL.
    pas de debug!! Connaissez vous une possibilite effective de debugger un service? j'ai fait un historique de ce qui est fait:

    j'obtiens:
    avant CoCreateInstance m_pListObjet = 0
    CoCreateInstance return S_OK
    FAILED(hr) m_pListObjet = 0

    Merci encore. J'espere ne pas abuser
    Bernard

    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
     
    // MIDL_DEFINE_GUID(CLSID, CLSID_CListObject,0x2AB23F66,0xE1C9,0x4316,0xA2,0x10,0xD4,0xC6,0xA1,0x06,0xE5,0x9A);
     
     
    int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
    {
         // Initialize OLE libraries  ou      CoInitialize(NULL);
    	if (!AfxOleInit())
    	{
    	     sprintf(chBuf, "erreur OLE init "); m_Key = m_Journal.WriteJournal(chBuf); // JOURNAL
    		_tprintf(_T("Fatal Error: OLE  initialization failed\n"));
      	       return 0;
    	}
     
           AfxEnableControlContainer();  // */
          CoInitialize(NULL);
    	..
    }
     
    bool CMyService::OnInit(void)
    {
    	     return CreateListObject();
    }
     
    bool CMyService::CreateListObject()
    {
    //    return false;
         m_pListObjet = NULL;
    	sprintf(chBuf, "avant  CoCreateInstance,  m_pListObjet = %x ", m_pListObjet); m_Key = m_Journal.WriteJournal(chBuf); // JOURNAL
     
    	HRESULT hr = ::CoCreateInstance(CLSID_CListObject,
                                        NULL,
                                        CLSCTX_INPROC_SERVER,
                                        IID_IUnknown,
                                        (LPVOID*)&m_pListObjet);
       // return false;
     
       if (FAILED(hr)) { 
    	   DWORD err = GetLastError(); 
    	    switch (err) {
    	    case S_OK :
    		    sprintf(chBuf, "CoCreateInstance  return S_OK");  m_Journal.WriteJournal(chBuf); // JOURNAL
    			break;
    	    case  REGDB_E_CLASSNOTREG:
    		    sprintf(chBuf, "REGDB_E_CLASSNOTREG"); m_Journal.WriteJournal(chBuf); // JOURNAL
    		    break;
    	    case  CLASS_E_NOAGGREGATION:
    		    sprintf(chBuf, "CLASS_E_NOAGGREGATION"); m_Journal.WriteJournal(chBuf); // JOURNAL
    		    break;
    	    case    CO_E_CLASSSTRING:
    		    sprintf(chBuf, "CO_E_CLASSSTRING"); m_Journal.WriteJournal(chBuf); // JOURNAL
    		    break;
    	    case E_NOINTERFACE :
    		    sprintf(chBuf, "E_NOINTERFACE"); m_Journal.WriteJournal(chBuf); // JOURNAL
    			break;
    		default: break; 
    		}
     
    	    sprintf(chBuf, "FAILED(hr)  m_pListObjet = %x ", m_pListObjet); m_Journal.WriteJournal(chBuf, m_Key); // JOURNAL
     
        }
        ASSERT(m_pListObjet);
        ...
    }

  4. #4
    Expert confirm�
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    F�vrier 2005
    Messages
    5 503
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 53
    Localisation : France, Val de Marne (�le de France)

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

    Informations forums :
    Inscription : F�vrier 2005
    Messages : 5 503
    Par d�faut
    Il y a beaucoup de chose qui me font tiquer dans ce truc.
    Vous semblez un peu jeune sur la plateforme Windows.
    Utilisez des technologies d'il y a 20 an quand on ne connait pas la plateforme, c'est toujours casse-gueule.

    1 seul service et 1 seul thread. non?
    Non, un service est un programme comme un autre, il est juste dans un contexte de s�curit� particulier et le manager des services fait le gendarme.
    On peut donc avoir autant de thread et de type d'appartment COM qu'avec les autres types de programmes.

    CLSCTX_INPROC_SERVER pas aggrege (ca marche ds le pgm source)
    Non, cela donne le type de composant que vous voulez instancier et le mode d'acc�s, pas le type d'appartment COM compatible avec ce composant.

    le CoCreateInstance marche (return S_OK) mais m_pListObjet reste NULL.
    et ne d�marre pas (TimeOut) avec le 2eme return apr�s le CoCreateInstance
    Faut savoir, c'est un Timeout sur l'appel de CoCreateInstance ou le fait que m_pListObjet reste NULL ???

    pas de debug!! Connaissez vous une possibilite effective de debugger un service?
    Comme dans l'article que vous donnez en r�f�rence, Debug View fonctionne de paire avec OutputDebugString (http://msdn.microsoft.com/en-us/libr...(v=vs.85).aspx).
    Mais la m�thode la plus simple est de d�bugger en mode "programme normal" car la majorit� des probl�mes n'ont rien � voir avec le fait qu'il soit lanc� par le service manager.

    Votre code est truff� de primitive "Afx...", Afx est le nom de code des MFC. Si vous n'utilisez pas les MFC, vous ne devriez avec aucune de ces primitives dans votre code.

    Quel est le type de "m_pListObjet" ?
    Utilisez des CComPtr pour simplifier et s�curiser votre code (http://msdn.microsoft.com/en-us/library/hh279683.aspx)

    Je suis un �ternel pessimiste, j'utiliserai plut�t SUCCEDED que FAILED (http://msdn.microsoft.com/en-us/libr...(v=vs.85).aspx)

  5. #5
    Membre du Club
    Inscrit en
    F�vrier 2011
    Messages
    6
    D�tails du profil
    Informations forums :
    Inscription : F�vrier 2011
    Messages : 6
    Par d�faut
    Citation Envoy� par bacelar Voir le message
    Il y a beaucoup de chose qui me font tiquer dans ce truc.
    Vous semblez un peu jeune sur la plateforme Windows.
    Utilisez des technologies d'il y a 20 an quand on ne connait pas la plateforme, c'est toujours casse-gueule.
    J'ai un pgm source et des manuels datant de 15 ans. Je suis seul.
    Vous pouvez evidemment interrompre la discussion, en me le signalant svp, si je vous enerve trop.


    je ne comprends pas la notion de "type d'appartment COM"!!


    Citation Envoy� par bacelar Voir le message
    Faut savoir, c'est un Timeout sur l'appel de CoCreateInstance ou le fait que m_pListObjet reste NULL ???
    je voudrais obtenir pListObject lors du start de CMyService:
    j'ai TimeOut si CoInitialize() est ds le start de CMyService.
    pListObject (du start de CMyService) reste NULL si le CoInitialize() est ds le main du pgm service

    Maintenant j'ai mis le CoCreateInstance, apres le coInitialized() ds le main et j'obtiens qqchose ds pListObject.
    Le compilateur se plaint a cause du
    - IID_PPV_ARGS ( error C2787: 'INotify' : no GUID has been associated with this object) au QueryInterface() car effectivement je ne l ai pas ds le .idl donc pas ds le .c cree lors de la creation de la dll des composantes.
    ou a cause de
    LPVOID* (error C2786: 'void' : invalid operand for __uuidof)

    Citation Envoy� par bacelar Voir le message
    Votre code est truff� de primitive "Afx...", Afx est le nom de code des MFC. Si vous n'utilisez pas les MFC, vous ne devriez avec aucune de ces primitives dans votre code.
    J'utilise MFC pour CString p.e. ou pour l'architecture Document-View... d'autre part. mon pgm de base CLS.exe l'utilise.

    Citation Envoy� par bacelar Voir le message
    Quel est le type de "m_pListObjet" ?
    m_pListobject etait un *IUnknown

    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
     
     
    /***************************************************************
    INotify.h
    Interface purement abstraite qui permet la notification bidirectionnelle entre les appliances entre-elles et avec l'application
    ****************************************************************/
     
    // {ACEA4745-E3D4-494E-8A98-288CD8EB482D}
    static const GUID IID_INotify  = 
    { 0xacea4745, 0xe3d4, 0x494e, { 0x8a, 0x98, 0x28, 0x8c, 0xd8, 0xeb, 0x48, 0x2d } };
     
     
    class INotify : public IUnknown
    {
    public:
        // Standard IUnknown interface functions
        virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid,
                                                         LPVOID* ppvObj) = 0;
        virtual ULONG STDMETHODCALLTYPE AddRef(void) = 0;
        virtual ULONG STDMETHODCALLTYPE Release(void) = 0;
     
        // This interface
        virtual HRESULT STDMETHODCALLTYPE SetClient(LPVOID pClientNotif,LPVOID pClientInvest, LPVOID name) = 0;
        virtual HRESULT STDMETHODCALLTYPE Notify(CInfo pinfo) = 0;
    };
     
     
     
    int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
    {
    	int nRetCode = 0;
     
    	CoInitialize(NULL);
     
    	 CComPtr<IListObject>  pListObject;
    	 HRESULT hr = pListObject.CoCreateInstance(CLSID_CListObject);
     
     
    	 ASSERT(pListObject);
     
     
    	// get a pointer to the m_pListObject's INotify interface(inotify.h) 
         CComPtr<INotify> m_pINotify;
         hr = pListObject->QueryInterface(IID_PPV_ARGS(&m_pINotify) );
         //hr = pListObject->QueryInterface((LPVOID*) &m_pINotify );
     
    	// get a pointer to the m_pListObjet's IInvestigation interface(iinvestigation.h) 
         CComPtr<IInvestigation> m_pInvest;
        if (pListObject->QueryInterface(IID_Investigation, (LPVOID*)&m_pInvest) != S_OK) {
            TRACE("IInvestigation not supported");
            return FALSE;
        }
     
        m_pINotify->SetClient(m_pINotify, m_pInvest, NULL);
     
     
    	// initialize MFC and print and error on failure
    	if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
    	{
    		_tprintf(_T("Fatal Error: MFC initialization failed\n"));
    		nRetCode = 1;
    	}
    	else
    	{
    		// Parse for standard arguments (install, uninstall, usage)
    		CMyService MyService;
    		if (!MyService.ParseStandardArgs(argc, argv))
    			MyService.StartService();
     
    		// When we get here, the service has been stopped
    		return MyService.m_Status.dwWin32ExitCode;
    	}
     
    	return nRetCode;
    }
    A suivre, Merci
    Bernard

  6. #6
    Expert �minent
    Avatar de M�dinoc
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par d�faut
    Pour permettre au __uuidof() de marcher sur ton interface, utilise la macro DECLSPEC_UUID, qui wrappe ceci.

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    class DECLSPEC_UUID("ACEA4745-E3D4-494E-8A98-288CD8EB482D") INotify : public IUnknown
    {
    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.

  7. #7
    Expert confirm�
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    F�vrier 2005
    Messages
    5 503
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 53
    Localisation : France, Val de Marne (�le de France)

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

    Informations forums :
    Inscription : F�vrier 2005
    Messages : 5 503
    Par d�faut
    je ne comprends pas la notion de "type d'appartment COM"!!
    Si vous ne voyez pas ce qu'est un COM appartment, le comportement de COM vous appara�tra toujours tr�s �trange.

    http://msdn.microsoft.com/en-us/library/ms809971.aspx

    Vous devez avoir le reflexe de tout reprendre dans un projet "jouet", pas de thrading complexe, pas de MFC ...

    Il faut bien comprendre qu'il faut appeler CoInitialize dans chaque thread, et toujours avant le moindre autre appel COM dans ce thread.

    CoInitialize permet de dire � COM, si le thread est STA ou MTA et donc dans quel appartment COM se site ce thread. Cela � un impacte sur la possibilit� ou non d'instancier tel ou tel type de composant.

    Maintenant j'ai mis le CoCreateInstance, apres le coInitialized() ds le main et j'obtiens qqchose ds pListObject.
    C'est la s�quence d'appels obligatoire, et pour chaque thread.

    J'utilise MFC pour CString p.e. ou pour l'architecture Document-View
    Les strings sont dans la STL depuis plus de 15 ans.
    "l'architecture Document-View", heu, je vous signale qu'un service n'a pas � avoir d'IHM, donc les MFC sont inutiles mais surtout dangereuses car elles contiennent de nombreux hacks qui sont potentiellement invalide dans le contexte des services.
    Si vous connaissez bien les MFC, il est possible d'�viter ces �cueils, mais ce n'est pas une sin�cure.

    Apr�s la lecture du lien sur les COM appartement, �tes-vous toujours bloqu� ?

  8. #8
    Expert �minent
    Avatar de M�dinoc
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par d�faut
    En effet, je ne vois pas l'int�r�t d'un code document/view dans un service. Pour les strings, utiliser selon les besoins des std::string, std::wstring ou _bstr_t.

    Et v�rifier que le ThreadingModel de l'objet est r�gl� (normalement sur "Apartment"), sinon c'est l'horreur.
    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.

Discussions similaires

  1. Lancement d'un VBS dans un Batch = Service KO ?
    Par ghohm dans le forum Scripts/Batch
    R�ponses: 1
    Dernier message: 26/02/2009, 07h16
  2. lancement sqlloader dans un service Windows
    Par DrZoune dans le forum C#
    R�ponses: 7
    Dernier message: 05/02/2008, 10h19
  3. R�ponses: 2
    Dernier message: 02/08/2004, 17h34
  4. R�ponses: 8
    Dernier message: 17/03/2004, 14h40

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