Page 1 of 1

NT Service Heelllpppp!!!

Posted: Mon Jan 05, 2004 9:48 pm
by johnfermor
This great NT Service code by Richard Eikeland was submitted some time ago but I can't get it to work as I get a "Line 28: Constant Already Declared with a different value: #SERVICE_ALL_ACCESS".

This question was also asked by AAA_2500 when the info was last posted (Dec 2003) but hasn't been answered.

Have I missed something here? I can't see any earlier declarations. Has the routine been broken by a PB update maybe? Is there a workaround?

Thanks everyone....

8O John


; Apr. 12, 2003
; Converted to PB by Richard Eikeland
; This code is posted as is with out any waranties.
;
#SERVICE_WIN32_OWN_PROCESS = $10
#SERVICE_WIN32_SHARE_PROCESS = $20
#SERVICE_WIN32 = #SERVICE_WIN32_OWN_PROCESS + #SERVICE_WIN32_SHARE_PROCESS
#SERVICE_ACCEPT_STOP = $1
#SERVICE_ACCEPT_PAUSE_CONTINUE = $2
#SERVICE_ACCEPT_SHUTDOWN = $4
#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

#STANDARD_RIGHTS_REQUIRED = $F0000
#SERVICE_QUERY_CONFIG = $1
#SERVICE_CHANGE_CONFIG = $2
#SERVICE_QUERY_STATUS = $4
#SERVICE_ENUMERATE_DEPENDENTS = $8
#SERVICE_START = $10
#SERVICE_STOP = $20
#SERVICE_PAUSE_CONTINUE = $40
#SERVICE_INTERROGATE = $80
#SERVICE_USER_DEFINED_CONTROL = $100
#SERVICE_ALL_ACCESS = #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_DEMAND_START = $3
#SERVICE_ERROR_NORMAL = $1

;- SERVICE_CONTROL
#SERVICE_CONTROL_STOP = $1
#SERVICE_CONTROL_PAUSE = $2
#SERVICE_CONTROL_CONTINUE = $3
#SERVICE_CONTROL_INTERROGATE = $4
#SERVICE_CONTROL_SHUTDOWN = $5


;-SERVICE_STATE
#SERVICE_STOPPED = $1
#SERVICE_START_PENDING = $2
#SERVICE_STOP_PENDING = $3
#SERVICE_RUNNING = $4
#SERVICE_CONTINUE_PENDING = $5
#SERVICE_PAUSE_PENDING = $6
#SERVICE_PAUSED = $7



Global ServiceStatus.SERVICE_STATUS, hServiceStatus.l, SERVICE_NAME.s, Finish.l
Declare Handler(fdwControl.l)
Declare ServiceMain(dwArgc.l, lpszArgv.l)
Declare WriteLog(Value.s)

Procedure Main()

hSCManager.l
hService.l
ServiceTableEntry.SERVICE_TABLE_ENTRY
b.l
cmd.s
;Change SERVICE_NAME and app name as needed
AppPath.s = "C:\Dev\PureBasic\workdir\NTService\MyService.exe"
SERVICE_NAME = "MyService"

cmd = Trim(LCase(ProgramParameter()))
Select cmd
Case "install" ;Install service on machine
hSCManager = OpenSCManager_(0, 0, #SC_MANAGER_CREATE_SERVICE)
hService = CreateService_(hSCManager, SERVICE_NAME, SERVICE_NAME, #SERVICE_ALL_ACCESS, #SERVICE_WIN32_OWN_PROCESS, #SERVICE_DEMAND_START, #SERVICE_ERROR_NORMAL, AppPath, 0, 0, 0, 0, 0)
CloseServiceHandle_(hService)
CloseServiceHandle_(hSCManager)
finish = 1
Case "uninstall" ;Remove service from machine
hSCManager = OpenSCManager_(0, 0, #SC_MANAGER_CREATE_SERVICE)
hService = OpenService_(hSCManager, SERVICE_NAME, #SERVICE_ALL_ACCESS)
DeleteService_(hService)
CloseServiceHandle_(hService)
CloseServiceHandle_(hSCManager)
finish = 1
Default
*sname.s = SERVICE_NAME
;Start the service
ServiceTableEntry\lpServiceName = @SERVICE_NAME
ServiceTableEntry\lpServiceProc = @ServiceMain()
b = StartServiceCtrlDispatcher_(@ServiceTableEntry)
WriteLog("Starting Service bResult=" + Str(b))
If b = 0
finish = 1
EndIf
EndSelect

Repeat

Until Finish =1

End

EndProcedure

Procedure Handler(fdwControl.l)
b.l

Select fdwControl
Case #SERVICE_CONTROL_PAUSE
;** Do whatever it takes To pause here.
ServiceStatus\dwCurrentState = #SERVICE_PAUSED
Case #SERVICE_CONTROL_CONTINUE
;** Do whatever it takes To continue here.
ServiceStatus\dwCurrentState = #SERVICE_RUNNING
Case #SERVICE_CONTROL_STOP
ServiceStatus\dwWin32ExitCode = 0
ServiceStatus\dwCurrentState = #SERVICE_STOP_PENDING
ServiceStatus\dwCheckPoint = 0
ServiceStatus\dwWaitHint = 0 ;Might want a time estimate
b = SetServiceStatus_(hServiceStatus, ServiceStatus)
;** Do whatever it takes to stop here.
Finish = 1
ServiceStatus\dwCurrentState = #SERVICE_STOPPED
Case #SERVICE_CONTROL_INTERROGATE
;Fall through To send current status.
Finish = 1
;Else
EndSelect
;Send current status.
b = SetServiceStatus_(hServiceStatus, ServiceStatus)
EndProcedure

Procedure ServiceMain(dwArgc.l, lpszArgv.l)
b.l
WriteLog("ServiceMain")
;Set initial state
ServiceStatus\dwServiceType = #SERVICE_WIN32_OWN_PROCESS
ServiceStatus\dwCurrentState = #SERVICE_START_PENDING
ServiceStatus\dwControlsAccepted = #SERVICE_ACCEPT_STOP | #SERVICE_ACCEPT_PAUSE_CONTINUE | #SERVICE_ACCEPT_SHUTDOWN
ServiceStatus\dwWin32ExitCode = 0
ServiceStatus\dwServiceSpecificExitCode = 0
ServiceStatus\dwCheckPoint = 0
ServiceStatus\dwWaitHint = 0

hServiceStatus = RegisterServiceCtrlHandler_(SERVICE_NAME, @Handler())
ServiceStatus\dwCurrentState = #SERVICE_START_PENDING
b = SetServiceStatus_(hServiceStatus, ServiceStatus)

;** Do Initialization Here

ServiceStatus\dwCurrentState = #SERVICE_RUNNING
b = SetServiceStatus_(hServiceStatus, ServiceStatus)

;** Perform tasks -- If none exit

;** If an error occurs the following should be used for shutting
;** down:
; SetServerStatus SERVICE_STOP_PENDING
; Clean up
; SetServerStatus SERVICE_STOPPED
EndProcedure

Procedure WriteLog(Value.s)
sfile.s = "MyServiceLog.txt"
If OpenFile(0, sfile)
WriteStringN(Value)
CloseFile(0)
Else
If CreateFile(0,sfile)

WriteStringN(Value)
CloseFile(0)
EndIf
EndIf

EndProcedure

Main()

Posted: Mon Jan 05, 2004 10:16 pm
by Proteus
If a constant is already declared, you give it another name...

Posted: Mon Jan 05, 2004 10:20 pm
by Karbon
Or don't define it yourself as it's already declared!

Posted: Mon Jan 05, 2004 10:21 pm
by Pupil
PB has quite a few precompiled constants already in '.res' files located in the '\residents' folder the constant in question is probably already there inside the 'windows.res' file. So you can do one of two things either use the one that is precompiled(assuming it's value is correct) i.e. comment out the line assigning the value to this constant in your program or you can just use a different name for the constant in your program...