Aide - Recherche - Membres - Calendrier
Version complète : [Résolu !] service windows en c++
Forum PC INpact > Systèmes, logiciels et lignes de codes > Programmation et Création web > Programmation (C, Perl, Python, Java...)
ginglese
bonjour,

auriez vous des exemples de codes c++ pour créer un service windows.

j'en ei créer un mais je dois passer par une ligne de commande dans mon programme pour l'ajouter, le supprimer, le démarrer et l'arrêter.

est il possible de faire tous cela dans des fonctions c++ et pas par un appel system ?

merci.
fabrice.roge
Tiens une petite classe de mon cru mon faire ce que tu veux assez simplement avec un service win32.

Win32ServiceInterface.h
**********************

#ifndef __WS32SA_
#define __WS32SA_
#include "stdafx.h"


#define SW32SA_STATE_STOP 0
#define SW32SA_STATE_RUN 1
#define SW32SA_STATE_PAUSE 2

typedef short SW32SA_STATE ;



class SimpleWin32ServiceAdapter
{
private:
LPSTR _lsz_name, _lsz_path;
LPSERVICE_MAIN_FUNCTION _ServiceMain;
LPHANDLER_FUNCTION _ServiceCtrlHandler;
SW32SA_STATE state;
SERVICE_STATUS_HANDLE hStatus;
SERVICE_STATUS status;

public:

SimpleWin32ServiceAdapter(LPCTSTR csz_name, LPCTSTR cs_binary_path,
LPSERVICE_MAIN_FUNCTION ServiceMain,LPHANDLER_FUNCTION ServiceCtrlHandler);
SimpleWin32ServiceAdapter(LPCTSTR csz_name, LPCTSTR cs_binary_path);
~SimpleWin32ServiceAdapter();

//predefined service control facilities
bool setState(SW32SA_STATE state);
SW32SA_STATE getState();
bool bootSvc();
bool registerCtrler();

//registration functions
bool registerService();
bool unregisterService();


};

typedef SimpleWin32ServiceAdapter * LPSW32SA, SW32SA ;
#endif
************************

Win32ServiceInterface.cpp
******************************************
#include "stdafx.h"
#include "Win32ServiceInterface.h"




SimpleWin32ServiceAdapter::SimpleWin32ServiceAdapter(LPCTSTR csz_name,LPCTSTR csz_path,
LPSERVICE_MAIN_FUNCTION pServiceMain,LPHANDLER_FUNCTION pServiceCtrlHandler)
{
if (csz_name)
this->_lsz_name = strdup(csz_name);
if (csz_path)
this->_lsz_path = strdup( csz_path);
if (pServiceMain)
this->_ServiceMain = pServiceMain;
if (pServiceCtrlHandler)
this->_ServiceCtrlHandler = pServiceCtrlHandler;
this->state=SW32SA_STATE_STOP;
}

SimpleWin32ServiceAdapter::SimpleWin32ServiceAdapter(LPCTSTR csz_name,LPCTSTR csz_path)
{
if (csz_name)
this->_lsz_name = strdup(csz_name);
if (csz_path)
this->_lsz_path = strdup( csz_path);
this->_ServiceCtrlHandler=NULL;
this->_ServiceMain=NULL;
this->state=SW32SA_STATE_STOP;
}



SimpleWin32ServiceAdapter::~SimpleWin32ServiceAdapter()
{
if (_lsz_name)
{
delete _lsz_name;_lsz_name = NULL;
}
if (_lsz_path)
{
delete _lsz_path;_lsz_path = NULL;
}
this->_ServiceCtrlHandler=NULL;
this->_ServiceMain=NULL;
}

bool SimpleWin32ServiceAdapter::setState(SW32SA_STATE state)
{
status.dwServiceType= SERVICE_WIN32_OWN_PROCESS;
status.dwControlsAccepted= SERVICE_ACCEPT_STOP;
status.dwWin32ExitCode=NO_ERROR ;
status.dwCheckPoint=0;
status.dwWaitHint=1000;
switch(state)
{
case (SW32SA_STATE_STOP):
status.dwCurrentState = SERVICE_STOPPED;
this->state = state;
break;
case (SW32SA_STATE_RUN):
status.dwCurrentState = SERVICE_RUNNING;
this->state = state;
break;
case (SW32SA_STATE_PAUSE):
status.dwCurrentState = SERVICE_PAUSED;
this->state = state;
break;
default:
return false;
break;
}
if (!SetServiceStatus(hStatus,&status))
return false;
return true;
}

SW32SA_STATE SimpleWin32ServiceAdapter::getState()
{
return this->state;
}

bool SimpleWin32ServiceAdapter::bootSvc( )
{
if ( !this->_ServiceMain)
return false;

SERVICE_TABLE_ENTRY ste_service ;
ste_service.lpServiceName = this->_lsz_name;
ste_service.lpServiceProc = this->_ServiceMain;
SERVICE_TABLE_ENTRY null_terminator = {NULL,NULL};

LPSERVICE_TABLE_ENTRY svc_table = new SERVICE_TABLE_ENTRY[2];
svc_table[0] = ste_service;
svc_table[1] = null_terminator;
if (! ( StartServiceCtrlDispatcher(svc_table) ) )
{
delete svc_table;svc_table = NULL;
return false;
}
delete svc_table;svc_table=NULL;

return true;
}



bool SimpleWin32ServiceAdapter::registerCtrler()
{
if (!this->_lsz_name || !this->_ServiceCtrlHandler )
return false;

if (
!(hStatus = RegisterServiceCtrlHandler(this->_lsz_name,this->_ServiceCtrlHandler))
)
{
hStatus=NULL;
return false;
}
return true;
}



bool SimpleWin32ServiceAdapter::registerService()
{
SC_HANDLE hSCManager, hSCService;

if ( ! (hSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_CREATE_SERVICE)) )
return false;

if ( !_lsz_name || !_lsz_path || ! (hSCService = CreateService(hSCManager,this->_lsz_name,this->_lsz_name, // service name to display
SERVICE_ALL_ACCESS, // desired access
SERVICE_WIN32_OWN_PROCESS, // service type
SERVICE_DISABLED, // start type
SERVICE_ERROR_NORMAL, // error control type
this->_lsz_path, // service's binary
NULL, // no load ordering group
NULL, // no tag identifier
NULL, // no dependencies
NULL, // LocalSystem account
NULL)
))// no password
return false;

CloseServiceHandle(hSCService);
hSCManager = NULL;
hSCService = NULL;

return true;
}

bool SimpleWin32ServiceAdapter::unregisterService()
{
SC_HANDLE hSCService, hSCManager ;


if (! ( hSCManager=OpenSCManager(NULL,NULL,STANDARD_RIGHTS_REQUIRED) ) )
return false;

if ( !_lsz_name || ! ( hSCService = OpenService ( hSCManager, this->_lsz_name, STANDARD_RIGHTS_REQUIRED) ) )
return false;

if ( ! ( DeleteService ( hSCService ) ) )
return false;

CloseServiceHandle(hSCService);
hSCManager = NULL;
hSCService = NULL;

return true;
}
******************************************

example d'utilisation dans ton main:

SW32SA w32_svc = SW32SA("my_service","C:\\projets\\versioning\\mon_service.exe 2");

l'ajouter:
w32_svc.registerService();
le supprimer :
w32_svc.unregisterService();

le démarrer:

w32_service = new SW32SA("my_service",
"C:\\projets\\versioning\\mon_service.exe 2",
&serviceMain,
&serviceCtrlHandler
);
if (!w32_service->bootSvc())
exit(1);

Tu dois déclarer pour celà serviceMain et serviceCtrlHandlr, examples:

void WINAPI serviceCtrlHandler(DWORD Opcode)
{
switch(Opcode)
{
case SERVICE_CONTROL_PAUSE:

w32_service->setState(SW32SA_STATE_STOP);
break;

case SERVICE_CONTROL_CONTINUE:

w32_service->setState(SW32SA_STATE_STOP);
break;

case SERVICE_CONTROL_STOP:

w32_service->setState(SW32SA_STATE_STOP);
break;

case SERVICE_CONTROL_INTERROGATE:

w32_service->setState(SW32SA_STATE_STOP);
break;
}
return;

}

void WINAPI serviceMain(DWORD argc,LPTSTR * argv)
{
//register the controller, must be done here : mandatory
if (!w32_service->registerCtrler())
{
LogFailure(MSG_START_FAILED);
exit(1);
}
w32_service->setState(SW32SA_STATE_RUN);


LogSuccess(MSG_START_SUCCESS );
while (w32_service->getState()==SW32SA_STATE_RUN)
{
//do some stuff here
// TODO: code your application's behavior here.
// ....
{
delete w32_service;w32_service = NULL;
exit(0);
}


Sinon je ne sais pas bien par quelle commande shell tu passes pour creér ou supprimer ton service, mais il est clair que ton programme doit analyser les paramètres qui lui sont passés par la ligne de commande pour savoir quoi faire (ici 2 indique que le service doit s'exécuter, et 1 ainsi que 0 pour respectivement le register et le unregister).

C'est un example comme un autre, mais si j'ai fait cette classe c'est pour avoir tous les appels système dans une seule classe plutot que de devoir tout recoder à chaque fois que je crée des services. C'est une sorte de wrapper en somme.

Juste une chose ça a été codé à l'arrache donc il peut y avoir des erreurs dedans même si c'est censer fonctionner correctement autant que je sache.

Bon courage.
ginglese
merci je vais voir cela de plus prêt.
ginglese
ok.

j'avais pas fait attention que l'on pouvait créer le service en appelant la methode create Service en dehors de l'exe du service lui-même .

du coup je peux faire mes appels d'ajout/suppresion et démmarage/ arrêt depuis mon programme sans passer par les commandes shells.



merci !
fabrice.roge
Ben de rien si je peux rendre service transpi.gif
ginglese
au fait comment fait on pour marquer le sujet en [Résolu] ?
theocrite
Tu édites ton premier post chinese.gif
ginglese
merci super Modo !
bowdown.gif
Ceci est une version "bas débit" de notre forum. Pour voir la version complète avec plus d'informations, la mise en page et les images, veuillez cliquer ici.
Invision Power Board © 2001-2009 Invision Power Services, Inc.