big problem with services and opendatabase
Posted: Wed May 18, 2016 5:16 pm
I need to make a service that will open a database.
here is the complete code that most have been found on the forum :
when i run this code, the database can't be open.
when i try only this
It works.
Is there a possibility to open a database in a service ?
here is the complete code that most have been found on the forum :
Code: Select all
EnableExplicit
Enumeration
#database
EndEnumeration
Define result
DeclareModule Service
Declare.b Install(ServiceName.s, DisplayName.s, Description.s)
Declare.b Uninstall(ServiceName.s)
Declare.b Run(ServiceName.s, *lpMainProc, *lpErrorProc)
Declare.b IsRunning()
Declare Logs(Message.s)
EndDeclareModule
Module Service
Structure SERVICE_PARAMS
ServiceName.s
*MainProc
*ErrorProc
CtrlStatus.l
EndStructure
Enumeration
#Log
EndEnumeration
Global ServiceParams.SERVICE_PARAMS
Global ServiceStatus.SERVICE_STATUS
Procedure Handler(fdwControl.l)
Select fdwControl
Case #SERVICE_CONTROL_INTERROGATE
Case #SERVICE_CONTROL_STOP
With ServiceStatus
\dwWin32ExitCode = 0
\dwCurrentState = #SERVICE_STOPPED
EndWith
Case #SERVICE_CONTROL_SHUTDOWN
With ServiceStatus
\dwWin32ExitCode = 0
\dwCurrentState = #SERVICE_STOPPED
EndWith
EndSelect
If (Not SetServiceStatus_(ServiceParams\CtrlStatus, @ServiceStatus))
If (ServiceParams\ErrorProc)
CallFunctionFast(ServiceParams\ErrorProc, GetLastError_())
EndIf
EndIf
EndProcedure
Procedure Loop()
ServiceParams\CtrlStatus = RegisterServiceCtrlHandler_(@ServiceParams\ServiceName, @Handler())
If (Not ServiceParams\CtrlStatus)
If (ServiceParams\ErrorProc)
CallFunctionFast(ServiceParams\ErrorProc, GetLastError_())
EndIf
ProcedureReturn
EndIf
ServiceStatus\dwCurrentState = #SERVICE_START_PENDING
If (Not SetServiceStatus_(ServiceParams\CtrlStatus, @ServiceStatus))
If (ServiceParams\ErrorProc)
CallFunctionFast(ServiceParams\ErrorProc, GetLastError_())
EndIf
EndIf
ServiceStatus\dwCurrentState = #SERVICE_RUNNING
If (Not SetServiceStatus_(ServiceParams\CtrlStatus, @ServiceStatus))
If (ServiceParams\ErrorProc)
CallFunctionFast(ServiceParams\ErrorProc, GetLastError_())
EndIf
EndIf
If (ServiceParams\MainProc)
CallFunctionFast(ServiceParams\MainProc)
EndIf
ServiceStatus\dwCurrentState = #SERVICE_STOP_PENDING
If (Not SetServiceStatus_(ServiceParams\CtrlStatus, @ServiceStatus))
If (ServiceParams\ErrorProc)
CallFunctionFast(ServiceParams\ErrorProc, GetLastError_())
EndIf
EndIf
ServiceStatus\dwCurrentState = #SERVICE_STOPPED
If (Not SetServiceStatus_(ServiceParams\CtrlStatus, @ServiceStatus))
If (ServiceParams\ErrorProc)
CallFunctionFast(ServiceParams\ErrorProc, GetLastError_())
EndIf
EndIf
EndProcedure
Procedure.b Install(ServiceName.s, DisplayName.s, Description.s)
Protected Result.b, hManager.l, hService.l, tSd.SERVICE_DESCRIPTION, BytesNeeded.l
hManager = OpenSCManager_(#Null, #Null, #SC_MANAGER_ALL_ACCESS)
If hManager
Define App.s = ProgramFilename()
hService = CreateService_(hManager, @ServiceName, @DisplayName, #SERVICE_ALL_ACCESS, #SERVICE_WIN32_OWN_PROCESS|#SERVICE_INTERACTIVE_PROCESS, #SERVICE_AUTO_START, #SERVICE_ERROR_NORMAL, @App, #Null, #Null, #Null, #Null, #Null)
If hService
tSd\lpDescription = @Description
If ChangeServiceConfig2_(hService, #SERVICE_CONFIG_DESCRIPTION, @tSd)
Result = StartService_(hService, #Null, #Null)
If (GetLastError_() = #ERROR_SERVICE_ALREADY_RUNNING)
Result = 1
EndIf
If (Not Result)
QueryServiceConfig_(hService, #Null, 0, @BytesNeeded)
If (GetLastError_() = #ERROR_INSUFFICIENT_BUFFER)
Define *ServiceConfig.QUERY_SERVICE_CONFIG = AllocateMemory(BytesNeeded)
If *ServiceConfig
If QueryServiceConfig_(hService, *ServiceConfig, BytesNeeded, @BytesNeeded)
Select *ServiceConfig\dwStartType
Case #SERVICE_AUTO_START, #SERVICE_DEMAND_START, #SERVICE_DISABLED
If ChangeServiceConfig_(hService, #SERVICE_NO_CHANGE, #SERVICE_DISABLED, #SERVICE_NO_CHANGE, #Null, #Null, #Null, #Null, #Null, #Null, #Null)
DeleteService_(hService)
EndIf
EndSelect
EndIf
FreeMemory(*ServiceConfig)
EndIf
EndIf
EndIf
EndIf
CloseServiceHandle_(hService)
EndIf
CloseServiceHandle_(hManager)
EndIf
ProcedureReturn Result
EndProcedure
Procedure.b Uninstall(ServiceName.s)
Protected Result.b, hManager.l, hService.l, lpServiceStatus.SERVICE_STATUS, dService, ServicesReturned.l, BytesNeeded.l
hManager = OpenSCManager_(#Null, #Null, #SC_MANAGER_ALL_ACCESS)
If hManager
hService = OpenService_(hManager, @ServiceName, #SERVICE_ALL_ACCESS)
If hService
ControlService_(hService, #SERVICE_CONTROL_STOP, @lpServiceStatus)
Select GetLastError_()
Case #ERROR_DEPENDENT_SERVICES_RUNNING
EnumDependentServices_(hService, #SERVICE_ACTIVE, #Null, 0, @BytesNeeded, @ServicesReturned)
If GetLastError_() = #ERROR_MORE_DATA
Dim Services.ENUM_SERVICE_STATUS((BytesNeeded / SizeOf(ENUM_SERVICE_STATUS)) + 1)
If EnumDependentServices_(hService, #SERVICE_ACTIVE, @Services(0), SizeOf(ENUM_SERVICE_STATUS) * ArraySize(Services()), @BytesNeeded, @ServicesReturned)
While ServicesReturned
If Services(ServicesReturned - 1)\lpServiceName
dService = OpenService_(hManager, Services(ServicesReturned - 1)\lpServiceName, #SERVICE_ALL_ACCESS)
If dService
ControlService_(dService, #SERVICE_CONTROL_STOP, @lpServiceStatus)
CloseServiceHandle_(dService)
EndIf
EndIf
ServicesReturned - 1
Wend
Delay(1000)
Result = ControlService_(hService, #SERVICE_CONTROL_STOP, @lpServiceStatus)
EndIf
FreeArray(Services())
EndIf
EndSelect
QueryServiceConfig_(hService, #Null, 0, @BytesNeeded)
If (GetLastError_() = #ERROR_INSUFFICIENT_BUFFER)
Define *ServiceConfig.QUERY_SERVICE_CONFIG = AllocateMemory(BytesNeeded)
If *ServiceConfig
If QueryServiceConfig_(hService, *ServiceConfig, BytesNeeded, @BytesNeeded)
Select *ServiceConfig\dwStartType
Case #SERVICE_AUTO_START, #SERVICE_DEMAND_START, #SERVICE_DISABLED
Result = ChangeServiceConfig_(hService, #SERVICE_NO_CHANGE, #SERVICE_DISABLED, #SERVICE_NO_CHANGE, #Null, #Null, #Null, #Null, #Null, #Null, #Null)
EndSelect
EndIf
FreeMemory(*ServiceConfig)
EndIf
EndIf
Result = DeleteService_(hService)
CloseServiceHandle_(hService)
EndIf
CloseServiceHandle_(hManager)
EndIf
ProcedureReturn Result
EndProcedure
Procedure.b Run(ServiceName.s, *lpMainProc, *lpErrorProc)
Protected Result.b, Table.SERVICE_TABLE_ENTRY
With ServiceParams
\ServiceName = ServiceName
\MainProc = *lpMainProc
\ErrorProc = *lpErrorProc
EndWith
With Table
\lpServiceName = @ServiceName
\lpServiceProc = @Loop()
EndWith
With ServiceStatus
\dwServiceType = #SERVICE_WIN32_OWN_PROCESS|#SERVICE_INTERACTIVE_PROCESS
\dwControlsAccepted = #SERVICE_ACCEPT_STOP|#SERVICE_ACCEPT_SHUTDOWN
\dwWin32ExitCode = 0
\dwServiceSpecificExitCode = 0
\dwCheckPoint = 0
\dwWaitHint = 0
EndWith
Result = StartServiceCtrlDispatcher_(@Table)
If (Result = #ERROR_SUCCESS)
If (ServiceParams\ErrorProc)
CallFunctionFast(ServiceParams\ErrorProc, GetLastError_())
EndIf
EndIf
ProcedureReturn Result
EndProcedure
Procedure.b IsRunning()
If (ServiceStatus\dwCurrentState = #SERVICE_RUNNING)
ProcedureReturn #True
EndIf
ProcedureReturn #False
EndProcedure
Procedure Logs(Message.s)
If OpenFile(#Log, "c:\serv.log")
FileSeek(#Log, Lof(#Log))
WriteStringN(#Log, FormatDate("%yyyy/%mm/%dd %hh:%ii:%ss", Date()) + " [" + Str(GetCurrentProcessId_()) + "] >> " + Message)
CloseFile(#Log)
EndIf
EndProcedure
EndModule
Global ServiceName.s = "pbService"
Global DisplayName.s = "pbService"
Global Description.s = "PureBasic"
Procedure ServiceMain()
Define flag.b = #True
Define result.l = 0
result = OpenDatabase(#database, "test", "sa", "sa", #PB_Database_ODBC)
Service::Logs(Str(result) )
While Service::IsRunning()
Service::Logs("boucle")
Delay(1000)
Wend
EndProcedure
Procedure ServiceError(Code.l)
Service::Logs("Error code service: " + StrU(Code, #PB_Word))
EndProcedure
Select ProgramParameter(0)
Case "-i"
If (Not Service::Install(ServiceName, DisplayName, Description))
Service::Logs("Service error install")
EndIf
Case "-d"
If (Not Service::Uninstall(ServiceName))
Service::Logs("Service error removed")
EndIf
Default
If (Not Service::Run(ServiceName, @ServiceMain(), @ServiceError()))
Service::Logs("Service error started")
EndIf
EndSelect
when i try only this
Code: Select all
EnableExplicit
Enumeration
#database
EndEnumeration
Define result
UseODBCDatabase()
result = OpenDatabase(#database, "test", "sa", "sa", #PB_Database_ODBC)
Debug result
Is there a possibility to open a database in a service ?