Voici mon probl=E8me :
J'ai une application Windows d=E9velopp=E9 en PowerBuilder (le drame....)
que je souhaite passer en Service, mais pas avec un truc a la srvany
ou autre car j'ai besoin de faire un "arret" propre de mon service, et
en plus, mon service doit en lancer ou arreter d'autre...
Alors pour resoudre ce probl=E8me, j'ai d=E9velopp=E9 une DLL en C qui me
permet d'utiliser les API Win32 pour d=E9clarer une serie de Threads qui
r=E9ponde au norme de Windows NT pour =EAtre vu comme un service (install=
=E9
avec InstSrv du toolkit).
Tout fonctionne =E0 merveille pour une instance de ce service.
Le probl=E8me, cette application dois =EAtre lanc=E9 6 fois, avec un passage
d'argument qui sera different a chaque fois :
MON_SERVICE_SRV1 : mon_exe.exe SRV1
MON_SERVICE_SRV2 : mon_exe.exe SRV2
MON_SERVICE_SRV3 : mon_exe.exe SRV3
MON_SERVICE_SRV4 : mon_exe.exe SRV4
MON_SERVICE_SRV5 : mon_exe.exe SRV5
MON_SERVICE_SRV6 : mon_exe.exe SRV6
Bon, je lance SRV1, =E7a marche... le 2 impecable, le 3 nickel... je me
dis tout marche impecable ;-)
Je lance le 4......... et la rien.....
Je stop le 3, je lance le 4 impecable....
En fait, apr=E8s plusieurs essai, je ne peut en lancer QUE 3 en m=EAme
temps!!!!!
Alors, ma question c'ets pourquoi ?? et comment =E9viter ce probl=E8me!!!
J'ai essay=E9 de copier 6 fois dans des dossiers differents l'exe et la
dll, mais le probl=E8me reste le m=EAme.
Comment peut-t-il y avoir un lien entre mes differents services ?
Je vous donne les source de ma DLL; dites moi si vous voyez un truc
anormal....
Dans PowerBuilder, je lance d=E9s le d=E9but de l'appli un
InitServiceThread
R=E9guli=E8rement (toute les secondes) je test TestServiceThread
Quand l'arret est demand=E9 (STOP_PENDING) j'arrete mon application
powerbuilder, et =E0 la fin de l'arret, j'appel DoneServiceThread
__________________________________________________________
HANDLE hThreadSynchro =3D NULL; // Flag
synchro d'arr=EAt du Thread
HANDLE ThreadHandleSynchro =3D NULL; // Handle du
thread synchro
HANDLE hThreadService =3D NULL; // Flag
Controleur de service
HANDLE ThreadHandleService =3D NULL; // Handle du
thread service
HANDLE hThreadDispatcher =3D NULL;
HANDLE hThreadStop =3D NULL;
SERVICE_STATUS ssStatus; // current status of
the service
SERVICE_STATUS_HANDLE sshStatusHandle;
DWORD dwGlobalErr;
BOOL far pascal TestServiceThread(){
return(hThreadSynchro !=3D (HANDLE)NULL);
}
VOID far pascal DoneServiceThread(){
if (hThreadSynchro !=3D (HANDLE)NULL)
SetEvent(hThreadSynchro);
if (hThreadService !=3D (HANDLE)NULL)
SetEvent(hThreadService);
if (hThreadDispatcher !=3D (HANDLE)NULL)
SetEvent(hThreadDispatcher);
if (hThreadStop !=3D (HANDLE)NULL)
SetEvent(hThreadStop);
}
VOID ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv){
DWORD dwWait;
sshStatusHandle =3D RegisterServiceCtrlHandler(*lpszArgv,
(LPHANDLER_FUNCTION)ServiceCtrl);
if (!sshStatusHandle) goto cleanup;
ssStatus.dwServiceType =3D
SERVICE_WIN32_OWN_PROCESS; // SERVICE_STATUS members that don't
change in example
ssStatus.dwServiceSpecificExitCode =3D 0;
if (!ReportStatusToSCMgr(SERVICE_START_PENDING , NO_ERROR, 1,
3000)) goto cleanup;
hThreadService =3D CreateEvent(NULL, TRUE, FALSE, NULL);
if (hThreadService =3D=3D (HANDLE)NULL) goto cleanup;
if (!ReportStatusToSCMgr(SERVICE_START_PENDING, NO_ERROR, 2,
3000)) goto cleanup;
if (!ReportStatusToSCMgr(SERVICE_RUNNING, NO_ERROR, 0, 0)) goto
cleanup;
dwWait =3D WaitForSingleObject(hThreadService, INFINITE); //
wait indefinitely
cleanup:
if (hThreadService !=3D (HANDLE)NULL) CloseHandle(hThreadService);
hThreadService =3D NULL;
if ((HANDLE)sshStatusHandle !=3D (HANDLE)NULL)
(VOID)ReportStatusToSCMgr(SERVICE_STOPPED, dwGlobalErr, 0, 0);
return;
}
VOID ServiceCtrl(DWORD dwCtrlCode){
DWORD dwWait;
DWORD dwState =3D SERVICE_RUNNING;
unsigned short i;
switch(dwCtrlCode) {
case SERVICE_CONTROL_PAUSE: // Pause the service if it is
running. non impl=E9ment=E9
break;
case SERVICE_CONTROL_CONTINUE: // Resume the paused service.
non impl=E9ment=E9
break;
case SERVICE_CONTROL_STOP: {// Stop the service.
dwState =3D SERVICE_STOP_PENDING;
if ((HANDLE)sshStatusHandle !=3D (HANDLE)NULL)
ReportStatusToSCMgr(SERVICE_STOP_PENDING, NO_ERROR, 1,
5000); // waithint
hThreadStop =3D CreateEvent(NULL, TRUE, FALSE,
NULL); // no name
if (hThreadSynchro !=3D (HANDLE)NULL)
SetEvent(hThreadSynchro);
for( i=3D2; i<20; i++){
if (hThreadStop !=3D (HANDLE)NULL) dwWait =3D
WaitForSingleObject(hThreadStop, 3000);
if (hThreadStop !=3D (HANDLE)NULL) {
CloseHandle(hThreadStop);
hThreadStop =3D NULL;
break;
}
else
ReportStatusToSCMgr(SERVICE_STOP_PENDING,NO_ERROR,i,5000); // On
informe le SCM qu'on est toujours en train de travailler
}
}
break;
case SERVICE_CONTROL_INTERROGATE:// Update the service status.
break;
default: // invalid control code
break;
}
// send a status response.
if (dwState !=3D SERVICE_STOP_PENDING) if((HANDLE)sshStatusHandle !=3D
(HANDLE)NULL) ReportStatusToSCMgr(dwState, NO_ERROR, 0, 0);
return;
}
BOOL ReportStatusToSCMgr(DWORD dwCurrentState, DWORD dwWin32ExitCode,
DWORD dwCheckPoint, DWORD dwWaitHint){
BOOL fResult =3D FALSE;
if ((HANDLE)sshStatusHandle !=3D (HANDLE)NULL){ // Disable control
requests until the service is started.
if (dwCurrentState =3D=3D SERVICE_START_PENDING)
ssStatus.dwControlsAccepted =3D 0;
else ssStatus.dwControlsAccepted =3D SERVICE_ACCEPT_STOP;
ssStatus.dwCurrentState =3D dwCurrentState;
ssStatus.dwWin32ExitCode =3D dwWin32ExitCode;
ssStatus.dwCheckPoint =3D dwCheckPoint;
ssStatus.dwWaitHint =3D dwWaitHint;
if (!(fResult =3D SetServiceStatus(sshStatusHandle, &ssStatus)))
{}
Sleep(100);
}
return fResult;
}
____________________________________________________
> J'ai lu votre code et je me pose quelques questions. Rappel:
" If StartServiceCtrlDispatcher succeeds, it connects the calling thread to the service control manager ****and does not return until all running services in the process have terminated****. The service control manager uses this connection to send control and service start requests to the ma in thread of the service process. The main thread acts as a dispatcher by invoking the appropriate "
Ce qui veut dire que dans votre fonction ThreadServiceCtrlDispatcher, l'event hThreadDispatcher n'est pas créé tant que le service n'est pas terminé. Ce qui pose un problème pour la routine DoneServiceThread qu i fait le SetEvent sur cet événement au moment où la décision est prise d'arrêter le service (appel à DoneServiceThread si j'ai bien compris). Mais comme l'objet n'est pas encore créé puisque dans ThreadServiceCtrlDispatche r, nous ne sommes pas encore revenu de l'appel à StartServiceCtrlDispatcher, no us voilà face au problème de la poule et de l'oeuf. Je peux faire une er reur de lecture mais il me semble que quelque chose ne va pas.
devrait se trouver avant l'appel à StartServiceCtrlDispatcher.
Oui en effet, j'avais pas remarqué; enfin, ce problème devrait aparaitre a la fermeture du service non? Donc, ce n'est pas celui la qui doit poser problème pour le lancement je pense...
Comme je vous le disais précédemment, je ne suis pas sûr que la sol ution à votre problème soit aussi simple que cela. Sinon personne ne se serait donner la peine de sortir un produit commercial pour le résoudre. Mais je n'y ai pas passé suffisamment de temps pour être formel sur ce point.
Oui, surement, mais ce qui est dommage, j'ai l'impression d'être très proche du résultat que je recherche... Il reste ce problème...
Par ailleurs, à quoi sert le Sleep (100) dans la fonction ReportStatusT oSCMgr.
La franchement je ne saurais vous répondre, je suis partis du code d'un collegue que je n'ai pas encore vu; il dois etre la la semaine prochaine, j'espere pouvoir lui demander si il a la moindre idée du problème.
Sinon, j'ai un peu avancé dans mon analyse : - Il y avait des Mutex de créé dans mon application qui ne servait plus en service (il servait à eviter que l'appli était lancé 2 fois avec les même parametres) je les ai donc enlevé.
- J'ai aussi instrumenté la DLL pour avoir des trace dans un fichier.
A première vu, que je soit en service 1, 2, 3 qui marche ou en 4 qui marche pas, j'ai les même trace...
En revanche, les traces de mes application PB diffère, j'ai essayer de comprendre, et j'ai l'impression que la création de certain objets dynamics ont échoué.
Ma question, n'y aurait-il pas une limitation de l'espace mèmoire aloué par le Windows Manager Service ? Je pensais qu'ils tournaient dans des espaces mémoire different, mais ce pourrait-t-il qu'ils partage un espace commun ? Limité à une certaine taille ?
Merci de votre aide en tout cas
Fabien PRORIOL
> J'ai lu votre code et je me pose quelques questions. Rappel:
"
If StartServiceCtrlDispatcher succeeds, it connects the calling thread to
the service control manager ****and does not return until all running
services in the process have terminated****. The service control manager
uses this connection to send control and service start requests to the ma in
thread of the service process. The main thread acts as a dispatcher by
invoking the appropriate
"
Ce qui veut dire que dans votre fonction ThreadServiceCtrlDispatcher,
l'event hThreadDispatcher n'est pas créé tant que le service n'est pas
terminé. Ce qui pose un problème pour la routine DoneServiceThread qu i fait
le SetEvent sur cet événement au moment où la décision est prise d'arrêter
le service (appel à DoneServiceThread si j'ai bien compris). Mais comme
l'objet n'est pas encore créé puisque dans ThreadServiceCtrlDispatche r, nous
ne sommes pas encore revenu de l'appel à StartServiceCtrlDispatcher, no us
voilà face au problème de la poule et de l'oeuf. Je peux faire une er reur de
lecture mais il me semble que quelque chose ne va pas.
devrait se trouver avant l'appel à StartServiceCtrlDispatcher.
Oui en effet, j'avais pas remarqué; enfin, ce problème devrait
aparaitre a la fermeture du service non?
Donc, ce n'est pas celui la qui doit poser problème pour le lancement
je pense...
Comme je vous le disais précédemment, je ne suis pas sûr que la sol ution à
votre problème soit aussi simple que cela. Sinon personne ne se serait
donner la peine de sortir un produit commercial pour le résoudre. Mais je
n'y ai pas passé suffisamment de temps pour être formel sur ce point.
Oui, surement, mais ce qui est dommage, j'ai l'impression d'être très
proche du résultat que je recherche...
Il reste ce problème...
Par ailleurs, à quoi sert le Sleep (100) dans la fonction ReportStatusT oSCMgr.
La franchement je ne saurais vous répondre, je suis partis du code
d'un collegue que je n'ai pas encore vu; il dois etre la la semaine
prochaine, j'espere pouvoir lui demander si il a la moindre idée du
problème.
Sinon, j'ai un peu avancé dans mon analyse :
- Il y avait des Mutex de créé dans mon application qui ne servait
plus en service (il servait à eviter que l'appli était lancé 2 fois
avec les même parametres) je les ai donc enlevé.
- J'ai aussi instrumenté la DLL pour avoir des trace dans un fichier.
A première vu, que je soit en service 1, 2, 3 qui marche ou en 4 qui
marche pas, j'ai les même trace...
En revanche, les traces de mes application PB diffère, j'ai essayer de
comprendre, et j'ai l'impression que la création de certain objets
dynamics ont échoué.
Ma question, n'y aurait-il pas une limitation de l'espace mèmoire
aloué par le Windows Manager Service ?
Je pensais qu'ils tournaient dans des espaces mémoire different, mais
ce pourrait-t-il qu'ils partage un espace commun ?
Limité à une certaine taille ?
> J'ai lu votre code et je me pose quelques questions. Rappel:
" If StartServiceCtrlDispatcher succeeds, it connects the calling thread to the service control manager ****and does not return until all running services in the process have terminated****. The service control manager uses this connection to send control and service start requests to the ma in thread of the service process. The main thread acts as a dispatcher by invoking the appropriate "
Ce qui veut dire que dans votre fonction ThreadServiceCtrlDispatcher, l'event hThreadDispatcher n'est pas créé tant que le service n'est pas terminé. Ce qui pose un problème pour la routine DoneServiceThread qu i fait le SetEvent sur cet événement au moment où la décision est prise d'arrêter le service (appel à DoneServiceThread si j'ai bien compris). Mais comme l'objet n'est pas encore créé puisque dans ThreadServiceCtrlDispatche r, nous ne sommes pas encore revenu de l'appel à StartServiceCtrlDispatcher, no us voilà face au problème de la poule et de l'oeuf. Je peux faire une er reur de lecture mais il me semble que quelque chose ne va pas.
devrait se trouver avant l'appel à StartServiceCtrlDispatcher.
Oui en effet, j'avais pas remarqué; enfin, ce problème devrait aparaitre a la fermeture du service non? Donc, ce n'est pas celui la qui doit poser problème pour le lancement je pense...
Comme je vous le disais précédemment, je ne suis pas sûr que la sol ution à votre problème soit aussi simple que cela. Sinon personne ne se serait donner la peine de sortir un produit commercial pour le résoudre. Mais je n'y ai pas passé suffisamment de temps pour être formel sur ce point.
Oui, surement, mais ce qui est dommage, j'ai l'impression d'être très proche du résultat que je recherche... Il reste ce problème...
Par ailleurs, à quoi sert le Sleep (100) dans la fonction ReportStatusT oSCMgr.
La franchement je ne saurais vous répondre, je suis partis du code d'un collegue que je n'ai pas encore vu; il dois etre la la semaine prochaine, j'espere pouvoir lui demander si il a la moindre idée du problème.
Sinon, j'ai un peu avancé dans mon analyse : - Il y avait des Mutex de créé dans mon application qui ne servait plus en service (il servait à eviter que l'appli était lancé 2 fois avec les même parametres) je les ai donc enlevé.
- J'ai aussi instrumenté la DLL pour avoir des trace dans un fichier.
A première vu, que je soit en service 1, 2, 3 qui marche ou en 4 qui marche pas, j'ai les même trace...
En revanche, les traces de mes application PB diffère, j'ai essayer de comprendre, et j'ai l'impression que la création de certain objets dynamics ont échoué.
Ma question, n'y aurait-il pas une limitation de l'espace mèmoire aloué par le Windows Manager Service ? Je pensais qu'ils tournaient dans des espaces mémoire different, mais ce pourrait-t-il qu'ils partage un espace commun ? Limité à une certaine taille ?
Merci de votre aide en tout cas
Fabien PRORIOL
Patrick Philippot
condo4 wrote:
Oui en effet, j'avais pas remarqué; enfin, ce problème devrait aparaitre a la fermeture du service non?
Oui. Mais cela signifie que les problèmes de synchro ne sont pas aussi "bétonnés" que vous le pensiez :-) .
A première vu, que je soit en service 1, 2, 3 qui marche ou en 4 qui marche pas, j'ai les même trace...
Vous pourriez utilser WinObj et Process Explorer pour vérifier quels objets kernels sont créés (events) et voir le nombre de threads activés par process. Cela donnerait sûrement quelques informations (http://www.microsoft.com/technet/sysinternals/default.mspx).
Ma question, n'y aurait-il pas une limitation de l'espace mèmoire aloué par le Windows Manager Service ?
Service Control Manager?
Je pensais qu'ils tournaient dans des espaces mémoire different, mais ce pourrait-t-il qu'ils partage un espace commun ? Limité à une certaine taille ?
Non. Les services sont des processus comme les autres.
-- Patrick Philippot - Microsoft MVP MainSoft Consulting Services www.mainsoft.fr
condo4 wrote:
Oui en effet, j'avais pas remarqué; enfin, ce problème devrait
aparaitre a la fermeture du service non?
Oui. Mais cela signifie que les problèmes de synchro ne sont pas aussi
"bétonnés" que vous le pensiez :-) .
A première vu, que je soit en service 1, 2, 3 qui marche ou en 4 qui
marche pas, j'ai les même trace...
Vous pourriez utilser WinObj et Process Explorer pour vérifier quels objets
kernels sont créés (events) et voir le nombre de threads activés par
process. Cela donnerait sûrement quelques informations
(http://www.microsoft.com/technet/sysinternals/default.mspx).
Ma question, n'y aurait-il pas une limitation de l'espace mèmoire
aloué par le Windows Manager Service ?
Service Control Manager?
Je pensais qu'ils tournaient dans des espaces mémoire different, mais
ce pourrait-t-il qu'ils partage un espace commun ?
Limité à une certaine taille ?
Non. Les services sont des processus comme les autres.
--
Patrick Philippot - Microsoft MVP
MainSoft Consulting Services
www.mainsoft.fr
Oui en effet, j'avais pas remarqué; enfin, ce problème devrait aparaitre a la fermeture du service non?
Oui. Mais cela signifie que les problèmes de synchro ne sont pas aussi "bétonnés" que vous le pensiez :-) .
A première vu, que je soit en service 1, 2, 3 qui marche ou en 4 qui marche pas, j'ai les même trace...
Vous pourriez utilser WinObj et Process Explorer pour vérifier quels objets kernels sont créés (events) et voir le nombre de threads activés par process. Cela donnerait sûrement quelques informations (http://www.microsoft.com/technet/sysinternals/default.mspx).
Ma question, n'y aurait-il pas une limitation de l'espace mèmoire aloué par le Windows Manager Service ?
Service Control Manager?
Je pensais qu'ils tournaient dans des espaces mémoire different, mais ce pourrait-t-il qu'ils partage un espace commun ? Limité à une certaine taille ?
Non. Les services sont des processus comme les autres.
-- Patrick Philippot - Microsoft MVP MainSoft Consulting Services www.mainsoft.fr
condo4
> > Oui en effet, j'avais pas remarqué; enfin, ce problème devrait > aparaitre a la fermeture du service non? Oui. Mais cela signifie que les problèmes de synchro ne sont pas aussi "bétonnés" que vous le pensiez :-) .
Certe c'est vrai :-)
> A première vu, que je soit en service 1, 2, 3 qui marche ou en 4 qui > marche pas, j'ai les même trace... Vous pourriez utilser WinObj et Process Explorer pour vérifier quels ob jets kernels sont créés (events) et voir le nombre de threads activés par process. Cela donnerait sûrement quelques informations (http://www.microsoft.com/technet/sysinternals/default.mspx).
Oui je peux voir l'état des service qui fonctionne, en revanche, pour celui qui meurt, il ne reste qu'environ 1 seconde voir 2 en activité avant de mourir, ce qui ne me laisse pas trop de temps pour voir ce qui se passe....
> Ma question, n'y aurait-il pas une limitation de l'espace mèmoire > aloué par le Windows Manager Service ? Service Control Manager?
Heu oui désolé :-)
> Je pensais qu'ils tournaient dans des espaces mémoire different, mais > ce pourrait-t-il qu'ils partage un espace commun ? > Limité à une certaine taille ? Non. Les services sont des processus comme les autres.
Ok
Bon, je suis en train de voir avec ma boite s'il ne veulent pas essayer de faire un test avec PBservice, mais c'est pas gagné....
D'un autre coté, je ne sais vraiment trop par ou continuer chercher....
> > Oui en effet, j'avais pas remarqué; enfin, ce problème devrait
> aparaitre a la fermeture du service non?
Oui. Mais cela signifie que les problèmes de synchro ne sont pas aussi
"bétonnés" que vous le pensiez :-) .
Certe c'est vrai :-)
> A première vu, que je soit en service 1, 2, 3 qui marche ou en 4 qui
> marche pas, j'ai les même trace...
Vous pourriez utilser WinObj et Process Explorer pour vérifier quels ob jets
kernels sont créés (events) et voir le nombre de threads activés par
process. Cela donnerait sûrement quelques informations
(http://www.microsoft.com/technet/sysinternals/default.mspx).
Oui je peux voir l'état des service qui fonctionne, en revanche, pour
celui qui meurt, il ne reste qu'environ 1 seconde voir 2 en activité
avant de mourir, ce qui ne me laisse pas trop de temps pour voir ce
qui se passe....
> Ma question, n'y aurait-il pas une limitation de l'espace mèmoire
> aloué par le Windows Manager Service ?
Service Control Manager?
Heu oui désolé :-)
> Je pensais qu'ils tournaient dans des espaces mémoire different, mais
> ce pourrait-t-il qu'ils partage un espace commun ?
> Limité à une certaine taille ?
Non. Les services sont des processus comme les autres.
Ok
Bon, je suis en train de voir avec ma boite s'il ne veulent pas
essayer de faire un test avec PBservice, mais c'est pas gagné....
D'un autre coté, je ne sais vraiment trop par ou continuer
chercher....
> > Oui en effet, j'avais pas remarqué; enfin, ce problème devrait > aparaitre a la fermeture du service non? Oui. Mais cela signifie que les problèmes de synchro ne sont pas aussi "bétonnés" que vous le pensiez :-) .
Certe c'est vrai :-)
> A première vu, que je soit en service 1, 2, 3 qui marche ou en 4 qui > marche pas, j'ai les même trace... Vous pourriez utilser WinObj et Process Explorer pour vérifier quels ob jets kernels sont créés (events) et voir le nombre de threads activés par process. Cela donnerait sûrement quelques informations (http://www.microsoft.com/technet/sysinternals/default.mspx).
Oui je peux voir l'état des service qui fonctionne, en revanche, pour celui qui meurt, il ne reste qu'environ 1 seconde voir 2 en activité avant de mourir, ce qui ne me laisse pas trop de temps pour voir ce qui se passe....
> Ma question, n'y aurait-il pas une limitation de l'espace mèmoire > aloué par le Windows Manager Service ? Service Control Manager?
Heu oui désolé :-)
> Je pensais qu'ils tournaient dans des espaces mémoire different, mais > ce pourrait-t-il qu'ils partage un espace commun ? > Limité à une certaine taille ? Non. Les services sont des processus comme les autres.
Ok
Bon, je suis en train de voir avec ma boite s'il ne veulent pas essayer de faire un test avec PBservice, mais c'est pas gagné....
D'un autre coté, je ne sais vraiment trop par ou continuer chercher....
Patrick Philippot
condo4 wrote:
Ce qui veut dire que dans votre fonction ThreadServiceCtrlDispatcher, l'event hThreadDispatcher n'est pas créé tant que le service n'est pas terminé. Ce qui pose un problème pour la routine DoneServiceThread qui fait le SetEvent sur cet événement au moment où la décision est prise d'arrêter le service (appel à DoneServiceThread si j'ai bien compris). Mais comme l'objet n'est pas encore créé puisque dans ThreadServiceCtrlDispatcher, nous ne sommes pas encore revenu de l'appel à StartServiceCtrlDispatcher, nous voilà face au problème de la poule et de l'oeuf. Je peux faire une erreur de lecture mais il me semble que quelque chose ne va pas.
devrait se trouver avant l'appel à StartServiceCtrlDispatcher.
Oui en effet, j'avais pas remarqué; enfin, ce problème devrait aparaitre a la fermeture du service non? Donc, ce n'est pas celui la qui doit poser problème pour le lancement je pense...
En fait, tout le code après le bloc "if (!StartServiceCtrlDispatcher(DispatchTable)) " dans ThreadServiceCtrlDispatcher ne sert à rien. On ne l'exécutera (sortie de StartServiceCtrlDispatcher) que lorsque le service sera terminé et donc il est inutile d'attendre sur un event qui fait redondance. Vous pouvez déjà simplifiez votre code en retirant tout ça et en supprimant les events et les tests/wait correspondants.
A première vu, que je soit en service 1, 2, 3 qui marche ou en 4 qui marche pas, j'ai les même trace...
Il va falloir traiter ça dans le débogueur.
1. Lancez les 3 premières instances du service de manière autonome. 2. Mettez des breakpoints aux points stratégiques dans le code de la DLL. 3. Lancez la DLL en mode debug depuis votre environnement de développement (VC++ ?) en précisant le nom de l'exécutable à lancer (la 4ème instance qui va charger la DLL) et l'argument ligne de commande. Quand l'exécutable appellera une fonction exportée par votre DLL, le débogueur prendra la main si un breakpoint est posé. 4. Vérifiez le chemin suivi et le point où cela bloque.
-- Patrick Philippot - Microsoft MVP MainSoft Consulting Services www.mainsoft.fr
condo4 wrote:
Ce qui veut dire que dans votre fonction ThreadServiceCtrlDispatcher,
l'event hThreadDispatcher n'est pas créé tant que le service n'est
pas terminé. Ce qui pose un problème pour la routine
DoneServiceThread qui fait le SetEvent sur cet événement au moment
où la décision est prise d'arrêter
le service (appel à DoneServiceThread si j'ai bien compris). Mais
comme l'objet n'est pas encore créé puisque dans
ThreadServiceCtrlDispatcher, nous ne sommes pas encore revenu de
l'appel à StartServiceCtrlDispatcher, nous voilà face au problème de
la poule et de l'oeuf. Je peux faire une erreur de lecture mais il
me semble que quelque chose ne va pas.
devrait se trouver avant l'appel à StartServiceCtrlDispatcher.
Oui en effet, j'avais pas remarqué; enfin, ce problème devrait
aparaitre a la fermeture du service non?
Donc, ce n'est pas celui la qui doit poser problème pour le lancement
je pense...
En fait, tout le code après le bloc "if
(!StartServiceCtrlDispatcher(DispatchTable)) " dans
ThreadServiceCtrlDispatcher ne sert à rien. On ne l'exécutera (sortie de
StartServiceCtrlDispatcher) que lorsque le service sera terminé et donc il
est inutile d'attendre sur un event qui fait redondance. Vous pouvez déjà
simplifiez votre code en retirant tout ça et en supprimant les events et les
tests/wait correspondants.
A première vu, que je soit en service 1, 2, 3 qui marche ou en 4 qui
marche pas, j'ai les même trace...
Il va falloir traiter ça dans le débogueur.
1. Lancez les 3 premières instances du service de manière autonome.
2. Mettez des breakpoints aux points stratégiques dans le code de la DLL.
3. Lancez la DLL en mode debug depuis votre environnement de développement
(VC++ ?) en précisant le nom de l'exécutable à lancer (la 4ème instance qui
va charger la DLL) et l'argument ligne de commande. Quand l'exécutable
appellera une fonction exportée par votre DLL, le débogueur prendra la main
si un breakpoint est posé.
4. Vérifiez le chemin suivi et le point où cela bloque.
--
Patrick Philippot - Microsoft MVP
MainSoft Consulting Services
www.mainsoft.fr
Ce qui veut dire que dans votre fonction ThreadServiceCtrlDispatcher, l'event hThreadDispatcher n'est pas créé tant que le service n'est pas terminé. Ce qui pose un problème pour la routine DoneServiceThread qui fait le SetEvent sur cet événement au moment où la décision est prise d'arrêter le service (appel à DoneServiceThread si j'ai bien compris). Mais comme l'objet n'est pas encore créé puisque dans ThreadServiceCtrlDispatcher, nous ne sommes pas encore revenu de l'appel à StartServiceCtrlDispatcher, nous voilà face au problème de la poule et de l'oeuf. Je peux faire une erreur de lecture mais il me semble que quelque chose ne va pas.
devrait se trouver avant l'appel à StartServiceCtrlDispatcher.
Oui en effet, j'avais pas remarqué; enfin, ce problème devrait aparaitre a la fermeture du service non? Donc, ce n'est pas celui la qui doit poser problème pour le lancement je pense...
En fait, tout le code après le bloc "if (!StartServiceCtrlDispatcher(DispatchTable)) " dans ThreadServiceCtrlDispatcher ne sert à rien. On ne l'exécutera (sortie de StartServiceCtrlDispatcher) que lorsque le service sera terminé et donc il est inutile d'attendre sur un event qui fait redondance. Vous pouvez déjà simplifiez votre code en retirant tout ça et en supprimant les events et les tests/wait correspondants.
A première vu, que je soit en service 1, 2, 3 qui marche ou en 4 qui marche pas, j'ai les même trace...
Il va falloir traiter ça dans le débogueur.
1. Lancez les 3 premières instances du service de manière autonome. 2. Mettez des breakpoints aux points stratégiques dans le code de la DLL. 3. Lancez la DLL en mode debug depuis votre environnement de développement (VC++ ?) en précisant le nom de l'exécutable à lancer (la 4ème instance qui va charger la DLL) et l'argument ligne de commande. Quand l'exécutable appellera une fonction exportée par votre DLL, le débogueur prendra la main si un breakpoint est posé. 4. Vérifiez le chemin suivi et le point où cela bloque.
-- Patrick Philippot - Microsoft MVP MainSoft Consulting Services www.mainsoft.fr
Patrick Philippot
condo4 wrote:
Le démarage du 4 service plante sur le sleep(100) de ReportStatusToSCMgr.
Avez-vous regardé dans l'Observateur d'événements si le SCM rapporte une erreur lors du démarage de la quatrième instance. Que dit GetLastError?
-- Patrick Philippot - Microsoft MVP MainSoft Consulting Services www.mainsoft.fr
condo4 wrote:
Le démarage du 4 service plante sur le sleep(100) de
ReportStatusToSCMgr.
Avez-vous regardé dans l'Observateur d'événements si le SCM rapporte une
erreur lors du démarage de la quatrième instance. Que dit GetLastError?
--
Patrick Philippot - Microsoft MVP
MainSoft Consulting Services
www.mainsoft.fr
Le démarage du 4 service plante sur le sleep(100) de ReportStatusToSCMgr.
Avez-vous regardé dans l'Observateur d'événements si le SCM rapporte une erreur lors du démarage de la quatrième instance. Que dit GetLastError?
-- Patrick Philippot - Microsoft MVP MainSoft Consulting Services www.mainsoft.fr
Patrick Philippot
Autre point qui me semble important:
Doc de StartServiceCtrlDispatcher
" The lpServiceTable parameter contains an entry for each service that can run in the calling process. Each entry specifies the ServiceMain function for that service. For SERVICE_WIN32_SHARE_PROCESS services, each entry must contain the name of a service. This name is the service name that was specified by the CreateService function when the service was installed. ****For SERVICE_WIN32_OWN_PROCESS services, the service name in the table entry is ignored****. "
Or c'est grâce à cette info que vous différenciez les services entre eux. Il y a donc probablement un problème dans la base de données du SCM. La solution est peut-être d'utiliser un seul processus de type SERVICE_WIN32_SHARE_PROCESS, ce qui peut changer sensiblement la structure du code.
-- Patrick Philippot - Microsoft MVP MainSoft Consulting Services www.mainsoft.fr
Autre point qui me semble important:
Doc de StartServiceCtrlDispatcher
"
The lpServiceTable parameter contains an entry for each service that can run
in the calling process. Each entry specifies the ServiceMain function for
that service. For SERVICE_WIN32_SHARE_PROCESS services, each entry must
contain the name of a service. This name is the service name that was
specified by the CreateService function when the service was installed.
****For SERVICE_WIN32_OWN_PROCESS services, the service name in the table
entry is ignored****.
"
Or c'est grâce à cette info que vous différenciez les services entre eux. Il
y a donc probablement un problème dans la base de données du SCM. La
solution est peut-être d'utiliser un seul processus de type
SERVICE_WIN32_SHARE_PROCESS, ce qui peut changer sensiblement la structure
du code.
--
Patrick Philippot - Microsoft MVP
MainSoft Consulting Services
www.mainsoft.fr
" The lpServiceTable parameter contains an entry for each service that can run in the calling process. Each entry specifies the ServiceMain function for that service. For SERVICE_WIN32_SHARE_PROCESS services, each entry must contain the name of a service. This name is the service name that was specified by the CreateService function when the service was installed. ****For SERVICE_WIN32_OWN_PROCESS services, the service name in the table entry is ignored****. "
Or c'est grâce à cette info que vous différenciez les services entre eux. Il y a donc probablement un problème dans la base de données du SCM. La solution est peut-être d'utiliser un seul processus de type SERVICE_WIN32_SHARE_PROCESS, ce qui peut changer sensiblement la structure du code.
-- Patrick Philippot - Microsoft MVP MainSoft Consulting Services www.mainsoft.fr
Patrick Philippot
condo4 wrote:
Merci, je vais faire ce test dans la journée, je vous tiens au courant du résultat.
Bonjour,
Le problème est-il résolu ou bien est-ce que je continue de suivre ce fil?
Cordialement.
-- Patrick Philippot - Microsoft MVP MainSoft Consulting Services www.mainsoft.fr
condo4 wrote:
Merci, je vais faire ce test dans la journée, je vous tiens au courant
du résultat.
Bonjour,
Le problème est-il résolu ou bien est-ce que je continue de suivre ce fil?
Cordialement.
--
Patrick Philippot - Microsoft MVP
MainSoft Consulting Services
www.mainsoft.fr
Merci, je vais faire ce test dans la journée, je vous tiens au courant du résultat.
Bonjour,
Le problème est-il résolu ou bien est-ce que je continue de suivre ce fil?
Cordialement.
-- Patrick Philippot - Microsoft MVP MainSoft Consulting Services www.mainsoft.fr
condo4
Bonjour, désolé, j'ai dus partire en déplacement, donc, le problème n'est toujours pas résolut. Aujourd'hui, je vais essayer d'installer mes services sur un Windows 2000 Serveur, pour voir si le problème est le même.
Je suis en train de reprendre vos suggestion (entre autre, je vais regarder le journal des erreur...)
donc, je vous tiens au courant de mes avancés....
Bonjour, désolé, j'ai dus partire en déplacement, donc, le problème
n'est toujours pas résolut.
Aujourd'hui, je vais essayer d'installer mes services sur un Windows
2000 Serveur, pour voir si le problème est le même.
Je suis en train de reprendre vos suggestion (entre autre, je vais
regarder le journal des erreur...)
Bonjour, désolé, j'ai dus partire en déplacement, donc, le problème n'est toujours pas résolut. Aujourd'hui, je vais essayer d'installer mes services sur un Windows 2000 Serveur, pour voir si le problème est le même.
Je suis en train de reprendre vos suggestion (entre autre, je vais regarder le journal des erreur...)
donc, je vous tiens au courant de mes avancés....
condo4
On 25 mai, 10:07, condo4 wrote:
Bonjour, désolé, j'ai dus partire en déplacement, donc, le problè me n'est toujours pas résolut. Aujourd'hui, je vais essayer d'installer mes services sur un Windows 2000 Serveur, pour voir si le problème est le même.
Je suis en train de reprendre vos suggestion (entre autre, je vais regarder le journal des erreur...)
donc, je vous tiens au courant de mes avancés....
Voila, j'ai donc fait un test sur le serveur. Ce qui m'a permi de découvrir un problème ailleur. J'ai l'impression que maintenant la DLL est stabilisé, et que le problème ne viens pas/plus d'elle (j'ai apporté les corrections que vous me conseillez).
En revanche, le problème semble etre maintenant dut à la connection PB avec la Base de Donnée... Donc, je vais creuser dans ce sens...
En faite, ce que j'aurais aimé savoir; c'est exactement, qu'est ce que ça change entre une appli normal et une service, a par le fait qu'elle dois repondre au point d'entré que ma DLL se charge...
Je sais qu'il utilise la session SYSTEM, mais au niveau droit, au niveau reseau... est-ce qu'il y a des differences majeur que j'ignore? Ou pourrais-je trouver une doc qui detail justement ces differences....
Merci beaucoup en tout cas de votre aide, elle m'a permit de mieu comprendre le fonctionnement et surtout de corriger certain détail qui me serait un jour ou l'autre tombé dessus. Aujourd'hui et le début de semaine prochaine, je vais travailler exclusiveement sur ce projet, j'espère arriver à comprendre un peu plus les problème restant....
@+Fab
On 25 mai, 10:07, condo4 <c...@saint-pal.com> wrote:
Bonjour, désolé, j'ai dus partire en déplacement, donc, le problè me
n'est toujours pas résolut.
Aujourd'hui, je vais essayer d'installer mes services sur un Windows
2000 Serveur, pour voir si le problème est le même.
Je suis en train de reprendre vos suggestion (entre autre, je vais
regarder le journal des erreur...)
donc, je vous tiens au courant de mes avancés....
Voila, j'ai donc fait un test sur le serveur.
Ce qui m'a permi de découvrir un problème ailleur.
J'ai l'impression que maintenant la DLL est stabilisé, et que le
problème ne viens pas/plus d'elle (j'ai apporté les corrections que
vous me conseillez).
En revanche, le problème semble etre maintenant dut à la connection PB
avec la Base de Donnée...
Donc, je vais creuser dans ce sens...
En faite, ce que j'aurais aimé savoir; c'est exactement, qu'est ce que
ça change entre une appli normal et une service, a par le fait qu'elle
dois repondre au point d'entré que ma DLL se charge...
Je sais qu'il utilise la session SYSTEM, mais au niveau droit, au
niveau reseau... est-ce qu'il y a des differences majeur que j'ignore?
Ou pourrais-je trouver une doc qui detail justement ces
differences....
Merci beaucoup en tout cas de votre aide, elle m'a permit de mieu
comprendre le fonctionnement et surtout de corriger certain détail qui
me serait un jour ou l'autre tombé dessus.
Aujourd'hui et le début de semaine prochaine, je vais travailler
exclusiveement sur ce projet, j'espère arriver à comprendre un peu
plus les problème restant....
Bonjour, désolé, j'ai dus partire en déplacement, donc, le problè me n'est toujours pas résolut. Aujourd'hui, je vais essayer d'installer mes services sur un Windows 2000 Serveur, pour voir si le problème est le même.
Je suis en train de reprendre vos suggestion (entre autre, je vais regarder le journal des erreur...)
donc, je vous tiens au courant de mes avancés....
Voila, j'ai donc fait un test sur le serveur. Ce qui m'a permi de découvrir un problème ailleur. J'ai l'impression que maintenant la DLL est stabilisé, et que le problème ne viens pas/plus d'elle (j'ai apporté les corrections que vous me conseillez).
En revanche, le problème semble etre maintenant dut à la connection PB avec la Base de Donnée... Donc, je vais creuser dans ce sens...
En faite, ce que j'aurais aimé savoir; c'est exactement, qu'est ce que ça change entre une appli normal et une service, a par le fait qu'elle dois repondre au point d'entré que ma DLL se charge...
Je sais qu'il utilise la session SYSTEM, mais au niveau droit, au niveau reseau... est-ce qu'il y a des differences majeur que j'ignore? Ou pourrais-je trouver une doc qui detail justement ces differences....
Merci beaucoup en tout cas de votre aide, elle m'a permit de mieu comprendre le fonctionnement et surtout de corriger certain détail qui me serait un jour ou l'autre tombé dessus. Aujourd'hui et le début de semaine prochaine, je vais travailler exclusiveement sur ce projet, j'espère arriver à comprendre un peu plus les problème restant....
@+Fab
Patrick Philippot
Bonjour,
En faite, ce que j'aurais aimé savoir; c'est exactement, qu'est ce que ça change entre une appli normal et une service, a par le fait qu'elle dois repondre au point d'entré que ma DLL se charge...
Sur le fond, quasiment rien. Le service doit effectivement fournir les points d'entrée requis et réagir aux sollicitations du système mais sinon, c'est un processus "normal". Par contre, comme un service n'est pas attaché à une session utilisateur particulière, certaines APIs ne fonctionnent pas ou pas de la même manière (en particulier celles qui prennent un numéro de session en argument ou qui ont besoin d'une info liée à la session courante). Par exemple, récupérer le nom de l'utilisateur courant pose des problèmes particuliers, surtout si on utilise le Fast User Switching : le service tourne en session 0 et les sessions utilisateurs peuvent être 0, 1,...,n. Sous Vista, c'est même pire puisque la session 0 est réservée aux services.
Tout ça peut poser 2 types de problèmes:
1. La communication du processus service avec les processus utilisateurs. Si vous utilisez des objets système comme des sémaphores, des mutexes, etc, il faut prendre soin de les créer dans le namespace Global (voir la doc).
2. L'interactivité avec l'utilisateur est limitée, même si on autorise le service à être interactif. Il vaut mieux avoir une appli utilisateur qui communique avec le service plutôt que de permettre au service de communiquer avec l'utilisateur directement (sauf dans les cas simples).
En fait, tout cela est assez logique si on comprend que le service tourne tout le temps et n'est pas lié à une session utilisateur.
La meilleure source d'info sur les services est probablement le MSDN.
Je sais qu'il utilise la session SYSTEM, mais au niveau droit, au niveau reseau... est-ce qu'il y a des differences majeur que j'ignore?
Le contexte de sécurité dans lequel s'exécute le service est celui défini par l'utilisateur spécifié dans la boîte de dialogue Propriétés du service. Il n'y a rien de spécifique en dehors de cela.
Bon courage.
-- Patrick Philippot - Microsoft MVP MainSoft Consulting Services www.mainsoft.fr
Bonjour,
En faite, ce que j'aurais aimé savoir; c'est exactement, qu'est ce que
ça change entre une appli normal et une service, a par le fait qu'elle
dois repondre au point d'entré que ma DLL se charge...
Sur le fond, quasiment rien. Le service doit effectivement fournir les
points d'entrée requis et réagir aux sollicitations du système mais sinon,
c'est un processus "normal". Par contre, comme un service n'est pas attaché
à une session utilisateur particulière, certaines APIs ne fonctionnent pas
ou pas de la même manière (en particulier celles qui prennent un numéro de
session en argument ou qui ont besoin d'une info liée à la session
courante). Par exemple, récupérer le nom de l'utilisateur courant pose des
problèmes particuliers, surtout si on utilise le Fast User Switching : le
service tourne en session 0 et les sessions utilisateurs peuvent être 0,
1,...,n. Sous Vista, c'est même pire puisque la session 0 est réservée aux
services.
Tout ça peut poser 2 types de problèmes:
1. La communication du processus service avec les processus utilisateurs. Si
vous utilisez des objets système comme des sémaphores, des mutexes, etc, il
faut prendre soin de les créer dans le namespace Global (voir la doc).
2. L'interactivité avec l'utilisateur est limitée, même si on autorise le
service à être interactif. Il vaut mieux avoir une appli utilisateur qui
communique avec le service plutôt que de permettre au service de communiquer
avec l'utilisateur directement (sauf dans les cas simples).
En fait, tout cela est assez logique si on comprend que le service tourne
tout le temps et n'est pas lié à une session utilisateur.
La meilleure source d'info sur les services est probablement le MSDN.
Je sais qu'il utilise la session SYSTEM, mais au niveau droit, au
niveau reseau... est-ce qu'il y a des differences majeur que j'ignore?
Le contexte de sécurité dans lequel s'exécute le service est celui défini
par l'utilisateur spécifié dans la boîte de dialogue Propriétés du service.
Il n'y a rien de spécifique en dehors de cela.
Bon courage.
--
Patrick Philippot - Microsoft MVP
MainSoft Consulting Services
www.mainsoft.fr
En faite, ce que j'aurais aimé savoir; c'est exactement, qu'est ce que ça change entre une appli normal et une service, a par le fait qu'elle dois repondre au point d'entré que ma DLL se charge...
Sur le fond, quasiment rien. Le service doit effectivement fournir les points d'entrée requis et réagir aux sollicitations du système mais sinon, c'est un processus "normal". Par contre, comme un service n'est pas attaché à une session utilisateur particulière, certaines APIs ne fonctionnent pas ou pas de la même manière (en particulier celles qui prennent un numéro de session en argument ou qui ont besoin d'une info liée à la session courante). Par exemple, récupérer le nom de l'utilisateur courant pose des problèmes particuliers, surtout si on utilise le Fast User Switching : le service tourne en session 0 et les sessions utilisateurs peuvent être 0, 1,...,n. Sous Vista, c'est même pire puisque la session 0 est réservée aux services.
Tout ça peut poser 2 types de problèmes:
1. La communication du processus service avec les processus utilisateurs. Si vous utilisez des objets système comme des sémaphores, des mutexes, etc, il faut prendre soin de les créer dans le namespace Global (voir la doc).
2. L'interactivité avec l'utilisateur est limitée, même si on autorise le service à être interactif. Il vaut mieux avoir une appli utilisateur qui communique avec le service plutôt que de permettre au service de communiquer avec l'utilisateur directement (sauf dans les cas simples).
En fait, tout cela est assez logique si on comprend que le service tourne tout le temps et n'est pas lié à une session utilisateur.
La meilleure source d'info sur les services est probablement le MSDN.
Je sais qu'il utilise la session SYSTEM, mais au niveau droit, au niveau reseau... est-ce qu'il y a des differences majeur que j'ignore?
Le contexte de sécurité dans lequel s'exécute le service est celui défini par l'utilisateur spécifié dans la boîte de dialogue Propriétés du service. Il n'y a rien de spécifique en dehors de cela.
Bon courage.
-- Patrick Philippot - Microsoft MVP MainSoft Consulting Services www.mainsoft.fr