You can probably tell, I've absolutely no idea about coding Services
Creating a Service ?
- 
				dontmailme
 - Enthusiast

 - Posts: 537
 - Joined: Wed Oct 29, 2003 10:35 am
 
Creating a Service ?
Can you create a Windows Service with PB ?
You can probably tell, I've absolutely no idea about coding Services
			
			
									
									You can probably tell, I've absolutely no idea about coding Services
Paid up PB User !
						- 
				Num3
 - PureBasic Expert

 - Posts: 2812
 - Joined: Fri Apr 25, 2003 4:51 pm
 - Location: Portugal, Lisbon
 - Contact:
 
Well this works ok under W2K and XP...
			
			
									
									
						Code: Select all
; 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 = "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()- 
				johnfermor
 - User

 - Posts: 29
 - Joined: Wed Dec 31, 2003 3:17 pm
 
Yeah, great code by Richard Eikeland but I too can't get it to work as I get a "Line 28: Constant Already Declared with a different value: #SERVICE_ALL_ACCESS". 
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....
Oh and aplogies for submitting this to the Off-Topic post!
			
			
									
									
						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....
Oh and aplogies for submitting this to the Off-Topic post!
>Workaround? Use the find/replace function to give 
>#SERVICE_ALL_ACCESS a new name.
I would assume that it has that name for a reason?!
It must have worked for somebody as it has been reposted in this forum several times... Is it broken because of an update to PB?
I am using PB3.30 updated to PB3.81.
Andy
			
			
									
									
						>#SERVICE_ALL_ACCESS a new name.
I would assume that it has that name for a reason?!
It must have worked for somebody as it has been reposted in this forum several times... Is it broken because of an update to PB?
I am using PB3.30 updated to PB3.81.
Andy
- 
				johnfermor
 - User

 - Posts: 29
 - Joined: Wed Dec 31, 2003 3:17 pm
 
Doh!
Yeah thanks ... Just thought of that ..
Although I don't get the error any more and the service installs correctly, how can I start and stop the service? I can do it manually by starting and stopping it but is there a way it can be started automatically as part of the install flag?
Sorry.. I'm a bit new to this service malarky... 8O
John
			
			
									
									
						Although I don't get the error any more and the service installs correctly, how can I start and stop the service? I can do it manually by starting and stopping it but is there a way it can be started automatically as part of the install flag?
Sorry.. I'm a bit new to this service malarky... 8O
John
> Constant Already Declared with a different value
Means the constant is already in use and can't be redefined. Just use another
constant name instead, to avoid the clash.
> I can't see any earlier declarations
Then PureBasic already has that constant declared (internally) which means
you should just be able to delete the declaration and compile the app with no
problem. Try it and let me know.
			
			
									
									
						Means the constant is already in use and can't be redefined. Just use another
constant name instead, to avoid the clash.
> I can't see any earlier declarations
Then PureBasic already has that constant declared (internally) which means
you should just be able to delete the declaration and compile the app with no
problem. Try it and let me know.
