Hi all,
I am in the need of creating a harbour app as a service.
AFIK there are two ways to do that. One could be using a win32 tool to
convert a console app into a win32 service. The other is to do it
programmatically. I prefer second one.
Well, I found some code and samples that create and install a service.
Should be compiled
Hbmk2 std l{win}xhb test
The idea is :
- First service should be installed. This is done by uncommenting
call to SvcInstall function in STARTSERVICE. This is done by calling
from console to application.
- Second is to start service. This is done by Services. After
installing service you should find a new entry in services list. There you
can start/pause/stop this service.
Well
This code is very bad L. The idea of a service is to start in a
different entry point than standard main.
So
if someone can help to get this work Ill be very happy J
Regards,
José Luis Capel
PS: some interesting links
<http://msdn.microsoft.com/en-us/library/ms685141%28v=VS.85%29.aspx>
http://msdn.microsoft.com/en-us/library/ms685141%28v=VS.85%29.aspx
<http://www.devx.com/cplus/Article/9857/0/page/1>
http://www.devx.com/cplus/Article/9857/0/page/1
Procedure Main()
LOCAL n
n := 0
DO WHILE .T.
hb_ToOutDebug("Status Service : "+STR(STATUS_SERVICE()))
ENDDO
RETURN NIL
INIT PROCEDURE Srv
StartService()
RETURN
#pragma BEGINDUMP
#include "windows.h"
#include "hbapi.h"
SERVICE_STATUS ServiceStatus;
SERVICE_STATUS_HANDLE hStatus;
void ServicioPruebas(int argc, char** argv);
void ControlHandler(DWORD request);
VOID SvcInstall();
HB_FUNC( STATUS_SERVICE )
{
hb_retnl( ServiceStatus.dwCurrentState );
}
HB_FUNC( STARTSERVICE )
{
SERVICE_TABLE_ENTRY ServiceTable[2];
ServiceTable[0].lpServiceName = "Servicio de Pruebas";
ServiceTable[0].lpServiceProc =
(LPSERVICE_MAIN_FUNCTION)ServicioPruebas;
ServiceTable[1].lpServiceName = NULL;
ServiceTable[1].lpServiceProc = NULL;
// Should be done first execution via console
// SvcInstall();
// Start the control dispatcher thread for our service
if(StartServiceCtrlDispatcher(ServiceTable))
{
OutputDebugString("CreateService OK\n");
}
else
{
if(GetLastError() == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT)
{
OutputDebugString("CreateService ERROR - NO ES SERVICIO\n");
}
else
{
OutputDebugString("CreateService ERROR - \n");
}
}
}
void ServicioPruebas(int argc, char** argv)
{
HB_SYMBOL_UNUSED(argc);
HB_SYMBOL_UNUSED(argv);
ServiceStatus.dwServiceType = SERVICE_WIN32;
ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP |
SERVICE_ACCEPT_SHUTDOWN;
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwServiceSpecificExitCode = 0;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;
hStatus = RegisterServiceCtrlHandler(
"Servicio de Pruebas",
(LPHANDLER_FUNCTION)ControlHandler);
if (hStatus == (SERVICE_STATUS_HANDLE)0)
{
// Registering Control Handler failed
return;
}
// We report the running status to SCM.
ServiceStatus.dwCurrentState = SERVICE_RUNNING;
SetServiceStatus (hStatus, &ServiceStatus);
return;
}
// Control handler function
void ControlHandler(DWORD request)
{
switch(request)
{
case SERVICE_CONTROL_STOP:
// WriteToLog("Monitoring stopped.");
OutputDebugString("ControlHandler STOP\n");
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus (hStatus, &ServiceStatus);
return;
case SERVICE_CONTROL_SHUTDOWN:
//WriteToLog("Monitoring stopped.");
OutputDebugString("ControlHandler SHUTDOWN\n");
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus (hStatus, &ServiceStatus);
return;
default:
break;
}
// Report current status
SetServiceStatus (hStatus, &ServiceStatus);
OutputDebugString("ControlHandler\n");
return;
}
//
// Purpose:
// Installs a service in the SCM database
//
// Parameters:
// None
//
// Return value:
// None
//
VOID SvcInstall()
{
SC_HANDLE schSCManager;
SC_HANDLE schService;
TCHAR szPath[MAX_PATH];
if( !GetModuleFileName( NULL, szPath, MAX_PATH ) )
{
printf("Cannot install service (%i)\n", GetLastError());
return;
}
// Get a handle to the SCM database.
schSCManager = OpenSCManager(
NULL, // local computer
NULL, // ServicesActive database
SC_MANAGER_ALL_ACCESS); // full access rights
if (NULL == schSCManager)
{
printf("OpenSCManager failed (%i)\n", GetLastError());
return;
}
// Create the service
schService = CreateService(
schSCManager, // SCM database
"Servicio de Pruebas", // name of service
"Servicio de Pruebas - Harbour", // service name
to display
SERVICE_ALL_ACCESS, // desired access
SERVICE_WIN32_OWN_PROCESS, // service type
SERVICE_DEMAND_START, // start type
SERVICE_ERROR_NORMAL, // error control type
szPath, // path to service's binary
NULL, // no load ordering group
NULL, // no tag identifier
NULL, // no dependencies
NULL, // LocalSystem account
NULL); // no password
if (schService == NULL)
{
printf("CreateService failed (%i)\n", GetLastError());
CloseServiceHandle(schSCManager);
return;
}
else printf("Service installed successfully\n");
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
}
_______________________________________________
Harbour mailing list (attachment size limit: 40KB)
[email protected]
http://lists.harbour-project.org/mailman/listinfo/harbour