ragazzi sono nuovo del forum e colgo l'occasione per salutare tutti(specialmente quelli che mi saranno d'aiuto:P)... sto provando a creare una classe in c++ che crei/installi e gestica un servizio di windows... il codice che sto per linkarvi viene correttamente compilato dal compilatore, installa il servizio su windows senza nessun problema, ma quando provo a lanciarlo mi da errore 1067 -.-'. PLEASE HELP ME!!!!
<servizio.h>
#include <process.h>
#include <iostream>
#include <tchar.h>
#include <stdio.h>
#include <windows.h>
#include <winbase.h>
#include <winsvc.h>
#ifndef SERVIZIO_H
#define SERVIZIO_H
const int nBufferSize = 500;
class servizio
{
public:
servizio();
void ServiceMainProc();
void set_cmd(char*);
char *get_cmd();
char *get_pExeFile();
void set_pServiceName(char*);
char *get_pServiceName();
void set_pLogFile(char*);
char *get_pLogFile();
virtual ~servizio();
protected:
virtual void ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv);
virtual void ServiceHandler(DWORD fdwControl);
private:
void Install();
void UnInstall();
void WriteLog(char* pMsg);
bool KillService();
bool RunService();
void ExecuteSubProcess();
friend void WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv);
friend void WINAPI ServiceHandler(DWORD fdwControl);
bool ProcessStarted;
SERVICE_STATUS_HANDLE hServiceStatusHandle;
SERVICE_STATUS ServiceStatus;
CRITICAL_SECTION myCS;
SERVICE_TABLE_ENTRY lpServiceStartTable[2];
char pServiceName[nBufferSize+1];
char pExeFile[nBufferSize+1];
char lpCmdLineData[nBufferSize+1];
char pLogFile[nBufferSize+1];
};
#endif // SERVIZIO_H
<servizio.cpp>
#include "..\include\servizio.h"
static servizio* Service;
void WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv)
{
Service->ServiceMain(dwArgc, lpszArgv);
}
void WINAPI ServiceHandler(DWORD fdwControl)
{
Service->ServiceHandler(fdwControl);
}
servizio::servizio()
{
//ctor
ProcessStarted = true;
}
servizio::~servizio()
{
//dtor
}
char *servizio::get_cmd()
{
return lpCmdLineData;
}
void servizio::set_cmd(char *b)
{
strcpy(lpCmdLineData, b);
}
char *servizio::get_pExeFile()
{
return pExeFile;
}
char *servizio::get_pServiceName()
{
return pServiceName;
}
void servizio::set_pServiceName(char *b)
{
strcpy(pServiceName, b);
}
char *servizio::get_pLogFile()
{
return pLogFile;
}
void servizio::set_pLogFile(char *b)
{
strcpy(pLogFile, b);
}
void servizio::ServiceMainProc()
{
::InitializeCriticalSection(&myCS);
// initialize variables for .exe and .log file names
char pModuleFile[nBufferSize+1];
DWORD dwSize = GetModuleFileName(NULL, pModuleFile, nBufferSize);
pModuleFile[dwSize] = 0;
if(dwSize>4 && pModuleFile[dwSize-4] == '.')
{
sprintf(pExeFile,"%s",pModuleFile);
pModuleFile[dwSize-4] = 0;
sprintf(pLogFile,"%s.log",pModuleFile);
}
set_pServiceName("servizio_test");
if(_stricmp("-i",get_cmd()) == 0 || _stricmp("-I",get_cmd()) == 0)
Install();
else if(_stricmp("-k",get_cmd()) == 0 || _stricmp("-K",get_cmd()) == 0)
KillService();
else if(_stricmp("-u",get_cmd()) == 0 || _stricmp("-U",get_cmd()) == 0)
UnInstall();
else if(_stricmp("-s",get_cmd()) == 0 || _stricmp("-S",get_cmd()) == 0)
RunService();
else
ExecuteSubProcess();
}
void servizio::Install()
{
SC_HANDLE schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_CREATE_SERVICE);
if (schSCManager==0)
{
long nError = GetLastError();
char pTemp[121];
sprintf(pTemp, "OpenSCManager failed, error code = %d\n", nError);
WriteLog(pTemp);
}
else
{
SC_HANDLE schService = CreateService
(
schSCManager, /* SCManager database */
get_pServiceName(), /* name of service */
get_pServiceName(), /* service name to display */
SERVICE_ALL_ACCESS, /* desired access */
SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROC ESS , /* service type */
SERVICE_AUTO_START, /* start type */
SERVICE_ERROR_NORMAL, /* error control type */
get_pExeFile(), /* service's binary */
NULL, /* no load ordering group */
NULL, /* no tag identifier */
NULL, /* no dependencies */
NULL, /* LocalSystem account */
NULL
); /* no password */
if (schService==0)
{
long nError = GetLastError();
char pTemp[121];
sprintf(pTemp, "Failed to create service %s, error code = %d\n", get_pServiceName(), nError);
WriteLog(pTemp);
}
else
{
char pTemp[121];
sprintf(pTemp, "Service %s installed\n", get_pServiceName());
WriteLog(pTemp);
CloseServiceHandle(schService);
}
CloseServiceHandle(schSCManager);
}
}
void servizio::UnInstall()
{
SC_HANDLE schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (schSCManager==0)
{
long nError = GetLastError();
char pTemp[121];
sprintf(pTemp, "OpenSCManager failed, error code = %d\n", nError);
WriteLog(pTemp);
}
else
{
SC_HANDLE schService = OpenService( schSCManager, get_pServiceName(), SERVICE_ALL_ACCESS);
if (schService==0)
{
long nError = GetLastError();
char pTemp[121];
sprintf(pTemp, "OpenService failed, error code = %d\n", nError);
WriteLog(pTemp);
}
else
{
if(!DeleteService(schService))
{
char pTemp[121];
sprintf(pTemp, "Failed to delete service %s\n", get_pServiceName());
WriteLog(pTemp);
}
else
{
char pTemp[121];
sprintf(pTemp, "Service %s removed\n",get_pServiceName());
WriteLog(pTemp);
}
CloseServiceHandle(schService);
}
CloseServiceHandle(schSCManager);
}
DeleteFile(get_pLogFile());
}
void servizio::WriteLog(char* pMsg)
{
// write error or other information into log file
::EnterCriticalSection(&myCS);
try
{
SYSTEMTIME oT;
::GetLocalTime(&oT);
FILE* pLog = fopen(get_pLogFile(),"a");
fprintf(pLog,"%02d/%02d/%04d, %02d:%02d:%02d\n %s",oT.wMonth,oT.wDay,oT.wYear,oT.wHour,oT.wMinute ,oT.wSecond,pMsg);
fclose(pLog);
} catch(...) {}
::LeaveCriticalSection(&myCS);
}
bool servizio::KillService()
{
// kill service with given name
SC_HANDLE schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (schSCManager==0)
{
long nError = GetLastError();
char pTemp[121];
sprintf(pTemp, "OpenSCManager failed, error code = %d\n", nError);
WriteLog(pTemp);
}
else
{
// open the service
SC_HANDLE schService = OpenService( schSCManager, get_pServiceName(), SERVICE_ALL_ACCESS);
if (schService==0)
{
long nError = GetLastError();
char pTemp[121];
sprintf(pTemp, "OpenService failed, error code = %d\n", nError);
WriteLog(pTemp);
}
else
{
// call ControlService to kill the given service
SERVICE_STATUS status;
if(ControlService(schService,SERVICE_CONTROL_STOP, &status))
{
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
return TRUE;
}
else
{
long nError = GetLastError();
char pTemp[121];
sprintf(pTemp, "ControlService failed, error code = %d\n", nError);
WriteLog(pTemp);
}
CloseServiceHandle(schService);
}
CloseServiceHandle(schSCManager);
}
return FALSE;
}
bool servizio::RunService()
{
// run service with given name
SC_HANDLE schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (schSCManager==0)
{
long nError = GetLastError();
char pTemp[121];
sprintf(pTemp, "OpenSCManager failed, error code = %d\n", nError);
WriteLog(pTemp);
}
else
{
// open the service
SC_HANDLE schService = OpenService( schSCManager, get_pServiceName(), SERVICE_ALL_ACCESS);
if (schService==0)
{
long nError = GetLastError();
char pTemp[121];
sprintf(pTemp, "OpenService failed, error code = %d\n", nError);
WriteLog(pTemp);
}
else
{
// call StartService to run the service
if(StartService(schService, 0, (const char**)NULL))
{
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
return TRUE;
}
else
{
long nError = GetLastError();
char pTemp[121];
sprintf(pTemp, "StartService failed, error code = %d\n", nError);
WriteLog(pTemp);
}
CloseServiceHandle(schService);
}
CloseServiceHandle(schSCManager);
}
return FALSE;
}
void servizio::ExecuteSubProcess()
{
lpServiceStartTable[0].lpServiceName = get_pServiceName();
lpServiceStartTable[0].lpServiceProc = ::ServiceMain;
lpServiceStartTable[1].lpServiceName = NULL;
lpServiceStartTable[1].lpServiceProc = NULL;
if(!StartServiceCtrlDispatcher(lpServiceStartTable ))
{
long nError = GetLastError();
char pTemp[121];
sprintf(pTemp, "StartServiceCtrlDispatcher failed, error code = %d\n", nError);
WriteLog(pTemp);
}
:eleteCriticalSection(&myCS);
WriteLog("sono partito\n");
}
void servizio::ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv)
{
DWORD status = 0;
DWORD specificError = 0xfffffff;
ServiceStatus.dwServiceType = SERVICE_WIN32;
ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_PAUSE_CONTINUE;
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwServiceSpecificExitCode = 0;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;
hServiceStatusHandle = RegisterServiceCtrlHandler(get_pServiceName(), ::ServiceHandler);
if (hServiceStatusHandle==0)
{
long nError = GetLastError();
char pTemp[121];
sprintf(pTemp, "RegisterServiceCtrlHandler failed, error code = %d\n", nError);
WriteLog(pTemp);
return;
}
// Initialization complete - report running status
ServiceStatus.dwCurrentState = SERVICE_RUNNING;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;
if(!SetServiceStatus(hServiceStatusHandle, &ServiceStatus))
{
long nError = GetLastError();
char pTemp[121];
sprintf(pTemp, "SetServiceStatus failed, error code = %d\n", nError);
WriteLog(pTemp);
}
ExecuteSubProcess();
}
void servizio::ServiceHandler(DWORD fdwControl)
{
switch(fdwControl)
{
case SERVICE_CONTROL_STOP:
case SERVICE_CONTROL_SHUTDOWN:
ProcessStarted = FALSE;
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;
// terminate all processes started by this service before shutdown
break;
case SERVICE_CONTROL_PAUSE:
ServiceStatus.dwCurrentState = SERVICE_PAUSED;
break;
case SERVICE_CONTROL_CONTINUE:
ServiceStatus.dwCurrentState = SERVICE_RUNNING;
break;
case SERVICE_CONTROL_INTERROGATE:
break;
//default:
//if(fdwControl>=128&&fdwControl<256)
//{
// ExecuteSubProcess();
//}
//else
//{
// char pTemp[121];
// sprintf(pTemp, "Unrecognized opcode %d\n", fdwControl);
// WriteLog(pTemp);
//}
};
if (!SetServiceStatus(hServiceStatusHandle, &ServiceStatus))
{
long nError = GetLastError();
char pTemp[121];
sprintf(pTemp, "SetServiceStatus failed, error code = %d\n", nError);
WriteLog(pTemp);
}
}
<main.cpp>
#include "include\servizio.h"
//using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
servizio *s;
s = new servizio();
if(argc >= 2)
s->set_cmd(argv[1]);
s->ServiceMainProc();
//s->~servizio();
return 0;
}