Windows Service Framework
Posted: Mon Mar 21, 2005 8:22 pm
A re-made example to create a Windows Service faster.
1. Just include the .pbi into your .pb.
2. Create a procedure ServiceProcedure(state.l) and monitor the state when the service is "Running" or "Paused".
3. Execute ServiceInit with the name of your service as the parameter.
4. To install the service, run the executable with -i as the parameter. And in Windows Services, Start your service.
5. To uninstall the service, stop the service and use -u to remove it from Windows Services.
To see what is happening, there will be a .log file created in the same folder as your executable with status every 1/10 of a sec.
Enjoy...
ServiceFramework.pbi
ServiceExample.pb
1. Just include the .pbi into your .pb.
2. Create a procedure ServiceProcedure(state.l) and monitor the state when the service is "Running" or "Paused".
3. Execute ServiceInit with the name of your service as the parameter.
4. To install the service, run the executable with -i as the parameter. And in Windows Services, Start your service.
5. To uninstall the service, stop the service and use -u to remove it from Windows Services.
To see what is happening, there will be a .log file created in the same folder as your executable with status every 1/10 of a sec.
Enjoy...
ServiceFramework.pbi
Code: Select all
Global AppHandle.l
Global AppHome.s
Global AppExeName.s
Global AppExeFileName.s
Global AppIniFileName.s
AppHandle.l = GetModuleHandle_(0)
AppIniFileName = Space(255)
GetModuleFileName_(AppHandle, @AppIniFileName, 255)
AppHome.s = GetPathPart(AppIniFileName)
AppExeFileName.s = GetFilePart(AppIniFileName)
AppExeName.s = Left(AppExeFileName, Len(AppExeFileName) - Len(GetExtensionPart(AppIniFileName)) - 1)
AppIniFileName.s = AppExeName + ".ini"
#READ_CONTROL = $20000
#STANDARD_RIGHTS_ALL = $1F0000
#STANDARD_RIGHTS_EXECUTE = (#READ_CONTROL)
#STANDARD_RIGHTS_READ = (#READ_CONTROL)
#STANDARD_RIGHTS_REQUIRED = $F0000
#STANDARD_RIGHTS_WRITE = (#READ_CONTROL)
#SERVICE_WIN32_OWN_PROCESS = $10
#SERVICE_WIN32_SHARE_PROCESS = $20
#SERVICE_WIN32 = #SERVICE_WIN32_OWN_PROCESS + #SERVICE_WIN32_SHARE_PROCESS
#SC_MANAGER_CONNECT = $1
#SC_MANAGER_CREATE_SERVICE = $2
#SC_MANAGER_ENUMERATE_SERVICE = $4
#SC_MANAGER_LOCK = $8
#SC_MANAGER_QUERY_LOCK_STATUS = $10
#SC_MANAGER_MODIFY_BOOT_CONFIG = $20
#SC_MANAGER_ALL_ACCESS_2 = (#STANDARD_RIGHTS_REQUIRED | #SC_MANAGER_CONNECT | #SC_MANAGER_CREATE_SERVICE | #SC_MANAGER_ENUMERATE_SERVICE | #SC_MANAGER_LOCK | #SC_MANAGER_QUERY_LOCK_STATUS | #SC_MANAGER_MODIFY_BOOT_CONFIG)
#SERVICE_ACCEPT_STOP = $1
#SERVICE_ACCEPT_PAUSE_CONTINUE = $2
#SERVICE_ACCEPT_SHUTDOWN = $4
#SERVICE_ACTIVE = $1
#SERVICE_ALL_ACCESS_2 = (#STANDARD_RIGHTS_REQUIRED | #SERVICE_QUERY_CONFIG | #SERVICE_CHANGE_CONFIG | #SERVICE_QUERY_STATUS | #SERVICE_ENUMERATE_DEPENDENTS | #SERVICE_START | #SERVICE_STOP | #SERVICE_PAUSE_CONTINUE | #SERVICE_INTERROGATE | #SERVICE_USER_DEFINED_CONTROL)
#SERVICE_CHANGE_CONFIG = $2
#SERVICE_CONTINUE_PENDING = $5
#SERVICE_CONTROL_CONTINUE = $3
#SERVICE_CONTROL_INTERROGATE = $4
#SERVICE_CONTROL_PAUSE = $2
#SERVICE_CONTROL_SHUTDOWN = $5
#SERVICE_CONTROL_STOP = $1
#SERVICE_DEMAND_START = $3
#SERVICE_ENUMERATE_DEPENDENTS = $8
#SERVICE_ERROR_NORMAL = $1
#SERVICE_INACTIVE = $2
#SERVICE_INTERROGATE = $80
#SERVICE_NO_CHANGE = $FFFF
#SERVICE_PAUSE_CONTINUE = $40
#SERVICE_PAUSE_PENDING = $6
#SERVICE_PAUSED = $7
#SERVICE_QUERY_CONFIG = $1
#SERVICE_QUERY_STATUS = $4
#SERVICE_RUNNING = $4
#SERVICE_START = $10
#SERVICE_START_PENDING = $2
#SERVICE_STATE_ALL = (#SERVICE_ACTIVE | #SERVICE_INACTIVE)
#SERVICE_STOP = $20
#SERVICE_STOP_PENDING = $3
#SERVICE_STOPPED = $1
#SERVICE_USER_DEFINED_CONTROL = $100
#SERVICE_CONFIG_DESCRIPTION = $1
#SERVICE_CONFIG_FAILURE_ACTIONS = $2
Global X_SERVICE_STATUS.SERVICE_STATUS
Global X_SERVICE_STATUS_HANDLE.l
Global X_SERVICE_RUNNING.l
Declare ServiceProcedure(ServiceState.l)
;
;
;
Procedure _WriteLog(LogMessage.s)
T_LOGFILE.s = AppHome + AppExeName + ".log"
T_HANDLE.l
If FileSize(T_LOGFILE) = -1
T_HANDLE = CreateFile(#PB_Any, T_LOGFILE)
Else
T_HANDLE = OpenFile(#PB_Any, T_LOGFILE)
FileSeek(Lof())
EndIf
WriteStringN(FormatDate("%yyyy/%mm/%dd,%hh:%ii:%ss,", Date()) + LogMessage)
CloseFile(T_HANDLE)
EndProcedure
;
;
;
Procedure ServiceHandler(OperationCode.l)
Select OperationCode
Case #SERVICE_CONTROL_PAUSE
X_SERVICE_STATUS\dwCurrentState = #SERVICE_PAUSED
SetServiceStatus_(X_SERVICE_STATUS_HANDLE, X_SERVICE_STATUS)
Case #SERVICE_CONTROL_CONTINUE
X_SERVICE_STATUS\dwCurrentState = #SERVICE_RUNNING
SetServiceStatus_(X_SERVICE_STATUS_HANDLE, X_SERVICE_STATUS)
Case #SERVICE_CONTROL_STOP
X_SERVICE_STATUS\dwWin32ExitCode = 0
X_SERVICE_STATUS\dwCheckPoint = 0
X_SERVICE_STATUS\dwWaitHint = 0
X_SERVICE_STATUS\dwCurrentState = #SERVICE_STOPPED
SetServiceStatus_(X_SERVICE_STATUS_HANDLE, X_SERVICE_STATUS)
X_SERVICE_RUNNING = #False
Case #SERVICE_CONTROL_INTERROGATE
X_SERVICE_RUNNING = #False
EndSelect
EndProcedure
;
;
;
Procedure ServiceMain()
X_SERVICE_STATUS\dwServiceType = #SERVICE_WIN32
X_SERVICE_STATUS\dwCurrentState = #SERVICE_START_PENDING
X_SERVICE_STATUS\dwControlsAccepted = #SERVICE_ACCEPT_STOP | #SERVICE_ACCEPT_PAUSE_CONTINUE
X_SERVICE_STATUS\dwWin32ExitCode = 0
X_SERVICE_STATUS\dwServiceSpecificExitCode = 0
X_SERVICE_STATUS\dwCheckPoint = 0
X_SERVICE_STATUS\dwWaitHint = 0
X_SERVICE_STATUS_HANDLE = RegisterServiceCtrlHandler_(AppExeName, @ServiceHandler())
X_SERVICE_STATUS\dwCurrentState = #SERVICE_RUNNING
SetServiceStatus_(X_SERVICE_STATUS_HANDLE, X_SERVICE_STATUS)
X_SERVICE_RUNNING = #True
While X_SERVICE_RUNNING
Sleep_(100)
ServiceProcedure(X_SERVICE_STATUS\dwCurrentState)
Wend
EndProcedure
;
;
;
Procedure ServiceInit(ServiceName.s)
T_TABLE_ENTRY.SERVICE_TABLE_ENTRY
T_SCMANAGER.l
T_SERVICE.l = 0
T_RETURNS.l = 1
T_PARAMETER.s = Trim(LCase(ProgramParameter()))
X_SERVICE_RUNNING = #False
If T_PARAMETER = ""
T_TABLE_ENTRY\lpServiceName = @AppExeName
T_TABLE_ENTRY\lpServiceProc = @ServiceMain()
If StartServiceCtrlDispatcher_(@T_TABLE_ENTRY)
_WriteLog("Service " + AppExeName + " dispatched.")
T_RETURNS = 0
EndIf
Else
T_SCMANAGER = OpenSCManager_(0, 0, #SC_MANAGER_ALL_ACCESS_2)
If T_SCMANAGER
Select T_PARAMETER
Case "-i"
_WriteLog("Installing service " + AppExeName + ".")
ServiceName = Trim(ServiceName)
If ServiceName = ""
ServiceName = AppExeName
EndIf
T_SERVICE = CreateService_(T_SCMANAGER, AppExeName, ServiceName, #SERVICE_ALL_ACCESS, #SERVICE_WIN32_OWN_PROCESS, #SERVICE_DEMAND_START, #SERVICE_ERROR_NORMAL, AppHome + AppExeFileName, 0, 0, 0, 0, 0)
If T_SERVICE
_WriteLog("Service installed succesfully.")
T_RETURNS = 0
Else
_WriteLog("Error installing service.")
EndIf
CloseServiceHandle_(T_SERVICE)
Case "-u"
_WriteLog("Uninstalling service " + AppExeName + ".")
T_SERVICE = OpenService_(T_SCMANAGER, AppExeName, #SERVICE_ALL_ACCESS_2)
If T_SERVICE
DeleteService_(T_SERVICE)
_WriteLog("Service uninstalled succesfully.")
T_RETURNS = 0
Else
_WriteLog("Error uninstalling service.")
EndIf
CloseServiceHandle_(T_SERVICE)
Default
_WriteLog("Unknown parameter " + T_PARAMETER + ". Use -i to install or -u to uninstall service.")
EndSelect
Else
_WriteLog("Error opening service control manager.")
EndIf
CloseServiceHandle_(T_SCMANAGER)
EndIf
_WriteLog("Program returned " + Str(T_RETURNS) + ".")
End T_RETURNS
EndProcedure
ServiceExample.pb
Code: Select all
XIncludeFile "C:\TEMP\ServiceFramework.pbi"
;
;
;
Procedure ServiceProcedure(State.l)
Select State
Case #SERVICE_RUNNING
_WriteLog("RUNNING:" + Str(State))
Case #SERVICE_PAUSED
_WriteLog("PAUSED:" + Str(State))
EndSelect
EndProcedure
ServiceInit("My Service")