NT Service HELP Please

Just starting out? Need help? Post your questions and find answers here.
ClueLess
Enthusiast
Enthusiast
Posts: 360
Joined: Sun Jan 11, 2009 1:04 am

NT Service HELP Please

Post by ClueLess »

I've been searching allover and coul'nt find an answer so I decided to ask the experts...

This is a service code whitvch works great:

Code: Select all

Declare Main()
Declare Service_Install()
Declare Service_Remove()
Declare Service_Start()
Declare Service_Stop()
Declare Service_MainLoop()
Declare Service_CtrlHandler(CtrlRequest.l)
Declare WriteToLog(entry.s)

Structure SVC_DESCRIPTION
  lpDescription.s
EndStructure

AppPath.s = ProgramFilename()
Global LogFile.s = GetPathPart(AppPath) + ReplaceString(GetFilePart(AppPath), ".exe",".log")

#MyService_Name         = "NetTax"
#MyService_AppName      = "NetTaxSvc.exe"
#MyService_DisplayName  = "NetTax"
#MyService_Description  = "NetTax Description"

Global ServiceStatus.SERVICE_STATUS
Global hStatus.l
Global Buffer.b 
 
Procedure Main()
  Select ProgramParameter(0)
    Case "-i"
      Service_Install()
    Case "-r"
      Service_Remove()
    Case "-s"
      Service_Start()
    Case "-k"
      Service_Stop()
  EndSelect
EndProcedure

Procedure WriteToLog(EventText.s)
  Protected hFile.l
  EventDate.s = FormatDate("%dd-%mm-%yyyy %hh:%ii:%ss", Date())

	hFile = OpenFile(#PB_Any, logfile)
	If hFile = #Null
	  ProcedureReturn #False
	EndIf
	FileSeek(hFile, Lof(hFile))
	WriteStringN(hFile, EventDate + " - " + EventText)
	CloseFile(hFile)
	ProcedureReturn #True
EndProcedure

Procedure Service_Install()
  Protected sDir.s
  Protected hSCManager.l, hService.l
  Protected SD.SVC_DESCRIPTION
  sDir        = GetCurrentDirectory() + #MyService_AppName
  hSCManager  = OpenSCManager_(#Null, #Null, #SC_MANAGER_ALL_ACCESS)
  hService    = CreateService_(hSCManager, #MyService_Name, #MyService_DisplayName, #SERVICE_ALL_ACCESS, #SERVICE_WIN32_OWN_PROCESS, #SERVICE_AUTO_START, #SERVICE_ERROR_NORMAL, sDir, #Null, #Null, #Null, #Null, #Null)
  SD\lpDescription = #MyService_Description
  ChangeServiceConfig2_(hService, #SERVICE_CONFIG_DESCRIPTION, @SD)
  CloseServiceHandle_(hService)
  
  WriteToLog("Service Installed")
EndProcedure

Procedure Service_Remove()
  Protected hSCManager.l, hServ.l
  hSCManager  = OpenSCManager_(#Null, #Null, #SC_MANAGER_ALL_ACCESS)
  hServ       = OpenService_(hSCManager, #MyService_Name, #SERVICE_ALL_ACCESS)
  DeleteService_(hServ)
  CloseServiceHandle_(hServ)
  CloseServiceHandle_(hSCManager)
  
  WriteToLog("Service Removed")
EndProcedure

Procedure Service_Start()
  Protected hSCManager.l, hServ.l
  hSCManager  = OpenSCManager_(#Null, #Null, #SC_MANAGER_ALL_ACCESS)
  hServ       = OpenService_(hSCManager, #MyService_Name, #SERVICE_ALL_ACCESS)
  StartService_(hServ, 0, #Null)
  CloseServiceHandle_(hServ)
  CloseServiceHandle_(hSCManager)

  WriteToLog("Service Started")
EndProcedure

Procedure Service_Stop()
  Protected hSCManager.l, hServ.l
  hSCManager  = OpenSCManager_(#Null, #Null, #SC_MANAGER_ALL_ACCESS)
  hServ       = OpenService_(hSCManager, #MyService_Name, #SERVICE_ALL_ACCESS)
  ControlService_(hServ, #SERVICE_CONTROL_STOP, @ServiceStatus)
  CloseServiceHandle_(hServ)
  CloseServiceHandle_(hSCManager)

  WriteToLog("Service Stoped")
EndProcedure

Procedure Service_MainLoop()
  Protected hError.l
  
  With ServiceStatus
    \dwServiceType             = #SERVICE_WIN32_OWN_PROCESS
    \dwCurrentState            = #SERVICE_START_PENDING
    \dwControlsAccepted        = #SERVICE_ACCEPT_STOP | #SERVICE_ACCEPT_SHUTDOWN | #SERVICE_ACCEPT_PAUSE_CONTINUE
    \dwWin32ExitCode           = 0
    \dwServiceSpecificExitCode = 0
    \dwCheckPoint              = 0
    \dwWaitHint                = 0
  EndWith
  hStatus = RegisterServiceCtrlHandler_(#MyService_Name, @Service_CtrlHandler()) 
  If hStatus = 0
    ProcedureReturn
  EndIf
  SetServiceStatus_(hStatus, @ServiceStatus)
  ServiceStatus\dwCurrentState = #SERVICE_RUNNING
  SetServiceStatus_(hStatus, @ServiceStatus)


; Main Loop
	Repeat
; Service Executing Code
	WritetoLog("Looping on Service Executing Code")
	Delay(10000)
	Until ServiceStatus\dwCurrentState <> #SERVICE_RUNNING

      ServiceStatus\dwCurrentState = #SERVICE_STOPPED
      ServiceStatus\dwWin32ExitCode= -1 
      SetServiceStatus_(hStatus, @ServiceStatus)
      ProcedureReturn #False
EndProcedure

Procedure Service_CtrlHandler(CtrlRequest.l)
  Select CtrlRequest
    Case #SERVICE_CONTROL_CONTINUE
      WriteToLog("service continue. ")
      With ServiceStatus
        \dwCurrentState = #SERVICE_RUNNING
      EndWith

    Case #SERVICE_CONTROL_PAUSE
     WriteToLog("service paused. " +)
      With ServiceStatus
        \dwCurrentState = #SERVICE_PAUSED
      EndWith

    Case #SERVICE_CONTROL_STOP
      WriteToLog("service stopped. ")
      With ServiceStatus
        \dwWin32ExitCode = 0
        \dwCurrentState = #SERVICE_STOPPED
      EndWith
  EndSelect

  SetServiceStatus_(hStatus, @ServiceStatus);
EndProcedure

Main()

But it doesn't report when service is started on the Service_CtrlHandler() procedure. How do I do that?

Note:
I'vr seen services code where is specified a user routine and a notify routine, like this: RunService("MyTestSvc", @ServiceFunction(), @ServiceNotify()), but lacks the install/start/stop/remove options which I need in this one. Any way to have both?

Thank You
SFSxOI
Addict
Addict
Posts: 2970
Joined: Sat Dec 31, 2005 5:24 pm
Location: Where ya would never look.....

Re: NT Service HELP Please

Post by SFSxOI »

I'm about the fartherest thing you will find from an expert :), but just some info. Although i'm not trying to promote copy-n-paste coding here, I had trouble with doing services myself and then found its already been done basically > http://www.purebasic.fr/english/viewtop ... 852#272852 and already has the install (create)/start/stop/remove options you said you needed.

and using that code to add a function to check the service status (Running, Stopped, etc...), something like this:

Code: Select all

#SERVICE_CONTINUE_PENDING = $00000005   ; The service Continue is pending. 
#SERVICE_PAUSE_PENDING = $00000006      ; The service pause is pending. 
#SERVICE_PAUSED = $00000007             ; The service is paused. 
#SERVICE_RUNNING = $00000004            ; The service is running. 
#SERVICE_START_PENDING = $00000002      ; The service is Starting. 
#SERVICE_STOP_PENDING = $00000003       ; The service is stopping. 
#SERVICE_STOPPED = $00000001            ; The service is Not running.

Global lpMachineName = #Null 
Global lpDatabaseName = #Null 
Global scmDesiredAccess = #SC_MANAGER_ALL_ACCESS
Global svcDesiredAccess = #SERVICE_ALL_ACCESS

Structure Status 
    dwServiceType.l  
    dwCurrentState.l 
    dwControlsAccepted.l  
    dwWin32ExitCode.l  
    dwServiceSpecificExitCode.l  
    dwCheckPoint.l  
    dwWaitHint.l 
EndStructure 
service.Status


Procedure.s SvcStatus(svcName.s) ; gets the service status
scmHandler = OpenSCManager_(lpMachineName, lpDatabaseName, scmDesiredAccess) 
svcHandler = OpenService_(scmHandler, svcName, svcDesiredAccess) 
QueryServiceStatus_(svcHandler, service.Status) 

Delay(10)

Select service\dwCurrentState
  Case #SERVICE_CONTINUE_PENDING
  svc_stat_return$ = "Continue pending"
  Case #SERVICE_PAUSE_PENDING
  svc_stat_return$ = "Pause pending"
  Case #SERVICE_PAUSED
  svc_stat_return$ = "Paused"
  Case #SERVICE_RUNNING
  svc_stat_return$ = "Running"
  Case #SERVICE_START_PENDING
  svc_stat_return$ = "Start pending"
  Case #SERVICE_STOP_PENDING
  svc_stat_return$ = "Stop pending"
  Case #SERVICE_STOPPED
  svc_stat_return$ = "Stopped"
  Default 
  svc_stat_return$ = "Unknown" 
EndSelect

CloseServiceHandle_(svcHandler) 
CloseServiceHandle_(scmHandler)

ProcedureReturn svc_stat_return$

EndProcedure

If SvcStatus("Winmgmt") = "Running" ; Is the Windows Management Instrumentation service running?
MessageRequester("Information", "The Windows Management Instrumentation service is running.", #PB_MessageRequester_Ok)
EndIf
The advantage of a 64 bit operating system over a 32 bit operating system comes down to only being twice the headache.
ClueLess
Enthusiast
Enthusiast
Posts: 360
Joined: Sun Jan 11, 2009 1:04 am

Re: NT Service HELP Please

Post by ClueLess »

Thank you for your reply

I've seen that post too. It seems very good but don't undestand how to integrate those two pieces of code into a single one where I can have a user defined function to do the service job and a notify function, with the options to install/start/stop/remove the service. As it is looks like I will need two apps.

your code for the notify is a good idea, and I think it can be used in my code. I would like however to have the notify function as shown on the first piece of code of the posting you sugested
Post Reply