WinServices.pbi [Win] Module

Share your advanced PureBasic knowledge/code with the community.
User avatar
HeX0R
Addict
Addict
Posts: 992
Joined: Mon Sep 20, 2004 7:12 am
Location: Hell

WinServices.pbi [Win] Module

Post by HeX0R »

This is just a recreation of my WinServices.pbi now powered by modules.

Code: Select all

; ==============================================================
; COMPILER OPTIONS:
;  [ ] Enable inline ASM support
;  [ ] Create unicode executable
;  [ ] Create threadsafe executable
;  [ ] Enable OnError lines support
;  [x] Enable XP skin support
;  [ ] Request Administrator mode for Windows Vista
;  [x] Request User mode for Windows Vista (no virtualization)
; Library Subsystem:
; File Format:        UTF-8
; Executable Format:  Windows
;
; Created on:         10/12/2015 20:56
; App/Lib-Name:       Win_Services.pbi
; Author:             HeX0R
; Version:            1.02
; Compiler:           PureBasic 5.41 LTS (Windows - x86)
; ==============================================================
;
; This little include is a rewrite of Rings' PBOSL_NTService
; You can give your app the possibility to work as service.
; You also can start/stop/pause/resume/install/uninstall services
;
DeclareModule WinService

	;Procedures to interact with services
	Declare StartService(ServiceName.s)
	Declare StopService(ServiceName.s)
	Declare PauseService(ServiceName.s)
	Declare ResumeService(ServiceName.s)
	;Procedures to create/remove services
	Declare InstallService(ServiceName.s, DisplayName.s, FileName.s, Description.s = "", StartParameter = #SERVICE_AUTO_START)
	Declare RemoveService(ServiceName.s)
	Declare StartRunning(ServiceName.s, *MainProcedure, *NotifyProcedure = #Null)
	;Procedure to quick-check state of services
	Declare GetServiceState(ServiceName.s)
	;Procedure to sllow User to Start/Stop/Pause/Resume Service
	Declare GrantAccess(ServiceName.s, UserName.s, Rights.i = #SERVICE_START | #SERVICE_STOP | #SERVICE_PAUSE_CONTINUE)
EndDeclareModule

;----- Internal Procedures

Module WinService

	#DACL_SECURITY_INFORMATION = $04
	#NO_INHERITANCE            = $00
	#SE_SERVICE                = $02
	#SET_ACCESS                = $02

	CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
	Macro StructureAlign : EndMacro
	CompilerElse
	Macro StructureAlign : Align 8 : EndMacro
	CompilerEndIf

	Prototype Notify_Procedure(ServiceStateChanged.i)

	Structure _TRUSTEE StructureAlign
		*pMultipleTrustee
		MultipleTrusteeOperation.l
		TrusteeForm.l
		TrusteeType.l
		*ptstrName
	EndStructure

	Structure EXPLICIT_ACCESS StructureAlign
		grfAccessPermissions.l
		grfAccessMode.l
		grfInheritance.l
		Trustee._TRUSTEE
	EndStructure

	Structure GlobalVars
		ServiceName.s
		hStatus.i
		Semaphore.i
		ThreadID.i
		ThreadID2.i
		*MainProc
		NotifyProc.Notify_Procedure
	EndStructure

	Global ServiceGlobals.GlobalVars
	Declare CtrlHandler(controlCode.l)

	Procedure DoService(ServiceName.s, DoWhat.i)
		Protected sStatus.SERVICE_STATUS
		Protected Result, schSCManager, schService

		;Internal procedure to change the status of a service.

		schSCManager = OpenSCManager_(0, 0, #SC_MANAGER_CONNECT)
		If schSCManager
			schService = OpenService_(schSCManager, @ServiceName, #GENERIC_EXECUTE)
			If schService
				If DoWhat <> 0
					Result = ControlService_(schService, DoWhat, sStatus)
				Else
					Result = StartService_(schService, 0, 0)
				EndIf
				CloseServiceHandle_(schService)
			EndIf
			CloseServiceHandle_(schSCManager)
		EndIf
		ProcedureReturn Result
	EndProcedure

	Procedure SendStatus(dwCurrentState, dwWin32ExitCode, dwServiceSpecificExitCode, dwCheckPoint, dwWaitHint)
		Protected sStatus.SERVICE_STATUS

		;Internal procedure to set the SERVICE_STATUS-structure of a Service.

		sStatus\dwServiceType  = #SERVICE_WIN32_OWN_PROCESS
		sStatus\dwCurrentState = dwCurrentState
		If dwCurrentState = #SERVICE_START_PENDING
			sStatus\dwControlsAccepted = 0
		Else
			sStatus\dwControlsAccepted = #SERVICE_ACCEPT_STOP | #SERVICE_ACCEPT_PAUSE_CONTINUE | #SERVICE_ACCEPT_SHUTDOWN
		EndIf
		;
		If dwServiceSpecificExitCode = 0
			sStatus\dwWin32ExitCode = dwWin32ExitCode
		Else
			sStatus\dwWin32ExitCode = #ERROR_SERVICE_SPECIFIC_ERROR
		EndIf

		sStatus\dwServiceSpecificExitCode  = dwServiceSpecificExitCode
		sStatus\dwCheckPoint               = dwCheckPoint
		sStatus\dwWaitHint                 = dwWaitHint

		;Pass the status record to the SCM
		SetServiceStatus_(ServiceGlobals\hStatus, sStatus)
	EndProcedure

	Procedure ServiceMain(argc.l, *argv)
		Protected dwNull

		;Internal Procedure to start the service and initialize the main procedure.

		With ServiceGlobals
			;immediately call Registration function
			\hStatus = RegisterServiceCtrlHandler_(@\ServiceName, @CtrlHandler())
			If \hStatus
				;Notify SCM of progress
				SendStatus(#SERVICE_START_PENDING, #NO_ERROR, 0, 1, 5000)

				;create the termination semaphore
				\Semaphore = CreateSemaphore()
				If \Semaphore
					;Notify SCM of progress
					SendStatus(#SERVICE_START_PENDING, #NO_ERROR, 0, 2, 1000)
					;Notify SCM of progress
					SendStatus(#SERVICE_START_PENDING, #NO_ERROR, 0, 3, 5000)
					;Start the service itself
					\ThreadID = CreateThread(\MainProc, #True)
					;\ThreadID = CreateThread(@__Service_Internal_DummyThread(), #True)
					If \ThreadID
						;Notify SCM of progress
						SendStatus(#SERVICE_RUNNING, #NO_ERROR, 0, 0, 0)
						;Wait for stop signal, and then terminate
						WaitSemaphore(\Semaphore)
						If IsThread(\ThreadID) And WaitThread(\ThreadID, 1000) = 0
							KillThread(\ThreadID)
						EndIf
						\ThreadID = 0
					EndIf
					FreeSemaphore(\Semaphore)
					\Semaphore = 0
				EndIf
				SendStatus(#SERVICE_STOPPED, #NO_ERROR, 0, 0, 0)
				\hStatus = #Null
			EndIf
		EndWith

	EndProcedure

	;----- Public Procedures

	Procedure GrantAccess(ServiceName.s, UserName.s, Rights.i = #SERVICE_START | #SERVICE_STOP | #SERVICE_PAUSE_CONTINUE)
		Protected *psd.SECURITY_DESCRIPTOR, *pacl, *pNewAcl
		Protected ea.EXPLICIT_ACCESS, Result

		;Procedure to grant a user access to pause/resume/start/stop the service.
		;(normaly not needed for WinXP)

		If GetNamedSecurityInfo_(ServiceName, #SE_SERVICE, #DACL_SECURITY_INFORMATION, #Null, #Null, @*pacl, 0, @*psd) = #ERROR_SUCCESS
			BuildExplicitAccessWithName_(@ea, @UserName, Rights, #SET_ACCESS, #NO_INHERITANCE)
			If SetEntriesInAcl_(1, @ea, *pacl, @*pNewAcl) = #ERROR_SUCCESS
				If SetNamedSecurityInfo_(ServiceName, #SE_SERVICE, #DACL_SECURITY_INFORMATION, #Null, #Null, *pNewAcl, 0) = #ERROR_SUCCESS
					Result = #True
				EndIf
			EndIf
		EndIf

		If *psd
			LocalFree_(*psd)
		EndIf
		If *pNewAcl
			LocalFree_(*pNewAcl)
		EndIf

		ProcedureReturn Result
	EndProcedure

	Procedure StartService(ServiceName.s) ;Start the service ServiceName

		ProcedureReturn DoService(ServiceName.s, 0)
	EndProcedure

	Procedure StopService(ServiceName.s) ;Stop the Service ServiceName

		ProcedureReturn DoService(ServiceName.s, #SERVICE_CONTROL_STOP)
	EndProcedure

	Procedure ResumeService(ServiceName.s) ;Resume the Service ServiceName

		ProcedureReturn DoService(ServiceName.s, #SERVICE_CONTROL_CONTINUE)
	EndProcedure

	Procedure PauseService(ServiceName.s) ;Pause the Service ServiceName

		ProcedureReturn DoService(ServiceName.s, #SERVICE_CONTROL_PAUSE)
	EndProcedure

	Procedure RemoveService(ServiceName.s) ;Remove the service ServiceName
		Protected sStatus.SERVICE_STATUS
		Protected Result, schSCManager, schService

		schSCManager = OpenSCManager_(0, 0, #SC_MANAGER_ALL_ACCESS)
		If schSCManager
			schService = OpenService_(schSCManager, @ServiceName, #SERVICE_ALL_ACCESS)
			If schService
				If ControlService_(schService, #SERVICE_CONTROL_STOP, sStatus) = 0
					Result = DeleteService_(schService)
				Else
					;Loop until its stopped, then delete it. It only deletes the SCM entry, not the executable.
					Repeat
						If QueryServiceStatus_(schService, sStatus ) = 0
							Break
						EndIf

						If sStatus\dwCurrentState = #SERVICE_STOPPED
							Result = DeleteService_(schService)
							Break
						EndIf
					ForEver
				EndIf
				CloseServiceHandle_(schService)
			EndIf
			CloseServiceHandle_(schSCManager)
		EndIf

		ProcedureReturn Result
	EndProcedure

	Procedure CtrlHandler(controlCode.l)
		Protected currentState, success, nopThread

		;Controlhandler, which gets called, whenever a service state has been changed.
		;If an optional notify-procedure has been set, it will also be called

		With ServiceGlobals
			currentState = GetServiceState(\ServiceName)
			Select controlCode
				Case #SERVICE_CONTROL_STOP
					currentState  = #SERVICE_STOP_PENDING
					;Tell the SCM what's happening
					SendStatus(#SERVICE_STOP_PENDING, #NO_ERROR, 0, 1, 5000)
					; Changed on 27.09.2005 by Peter Tübben (aka Kiffi)

					;First notify, otherwise it will be to late...
					If \NotifyProc
						\NotifyProc(controlCode)
					EndIf
					SignalSemaphore(\Semaphore)
					ProcedureReturn
				Case #SERVICE_CONTROL_PAUSE
					SendStatus(#SERVICE_PAUSE_PENDING, #NO_ERROR, 0, 1, 1000)
					PauseThread(\ThreadID)
					currentState  = #SERVICE_PAUSED
				Case #SERVICE_CONTROL_CONTINUE
					SendStatus(#SERVICE_CONTINUE_PENDING, #NO_ERROR, 0, 1, 1000)
					ResumeThread(\ThreadID)
					currentState  = #SERVICE_RUNNING
				Case #SERVICE_CONTROL_INTERROGATE
					; it will fall to bottom and send status
					;Could do cleanup here but it must be very quick.
				Case #SERVICE_CONTROL_SHUTDOWN
					;The service is notified when system
					;shutdown occurs.
					;Do nothing on shutdown.
			EndSelect

			SendStatus(currentState, #NO_ERROR, 0, 0, 0)
			If \NotifyProc
				\NotifyProc(controlCode)
			EndIf
		EndWith

	EndProcedure

	Procedure StartRunning(ServiceName.s, *MainProcedure, *NotifyProcedure = #Null)
		Protected Result

		;Call this procedure, do start the service (when it is trying to start with a state of #SERVICE_START_PENDING)
		;MainProcedure should look like this: MyMainProcedure(IsService.i)
		;NotifyProcedure (optional) should look like this: MyNotifyProcedure(NewServiceState.i)

		With ServiceGlobals


			If \hStatus = #Null And *MainProcedure <> #Null
				;o.k. now lets go!
				\MainProc       = *MainProcedure
				\NotifyProc     = *NotifyProcedure
				\ServiceName    = ServiceName

				Dim sTable.SERVICE_TABLE_ENTRY(1)
				sTable(0)\lpServiceProc = @ServiceMain()
				sTable(0)\lpServiceName = @ServiceName
				Result                  = StartServiceCtrlDispatcher_(@sTable())
			EndIf
		EndWith

		ProcedureReturn Result
	EndProcedure

	Procedure InstallService(ServiceName.s, DisplayName.s, FileName.s, Description.s = "", StartParameter = #SERVICE_AUTO_START);Installs a service and starts it
		Protected sStatus.SERVICE_STATUS
		Protected dwDesiredAccess = #SERVICE_ALL_ACCESS
		Protected dwServiceType   = #SERVICE_WIN32_OWN_PROCESS; | #SERVICE_INTERACTIVE_PROCESS ;<- this flag won't work that perfect on Win7, so better don't use it
		Protected dwErrorControl  = #SERVICE_ERROR_NORMAL
		Protected schSCManager, schService
		Protected Result, hKey, sTopKey, sKeyName.s, GetHandle

		schSCManager = OpenSCManager_(0, 0, #SC_MANAGER_CREATE_SERVICE | #SC_MANAGER_CONNECT)
		If schSCManager
			schService = CreateService_(schSCManager, @ServiceName, @DisplayName, dwDesiredAccess, dwServiceType, StartParameter, dwErrorControl, @FileName, 0, 0, 0, 0, 0)
			If schService
				Result = #True
				If QueryServiceStatus_(schService, @sStatus)
					If sStatus\dwCurrentState = #SERVICE_STOPPED
						If StartParameter = #SERVICE_AUTO_START Or StartParameter = #SERVICE_DEMAND_START
							Result = StartService_(schService, 0, 0)
						EndIf
					EndIf
				EndIf
				CloseServiceHandle_(schService)
			EndIf
			CloseServiceHandle_(schSCManager)
		EndIf

		If schSCManager And schService And Result And Description
			sTopKey   = #HKEY_LOCAL_MACHINE
			sKeyName  = "SYSTEM\CurrentControlSet\Services\" + Servicename
			GetHandle = RegOpenKeyEx_(stopKey, sKeyName, 0, #KEY_WRITE, @hKey)
			If GetHandle = #ERROR_SUCCESS
				GetHandle = RegSetValueEx_(hkey, "Description", 0, #REG_SZ, @Description, StringByteLength(Description) + SizeOf(CHARACTER))
			EndIf
			RegCloseKey_(hkey)
		EndIf

		ProcedureReturn Result
	EndProcedure

	Procedure GetServiceState(ServiceName.s)
		Protected schSCManager, schService
		Protected sStatus.SERVICE_STATUS
		Protected Result

		;Get the State of the Service ServiceName

		schSCManager = OpenSCManager_(0, 0, #SC_MANAGER_CONNECT)
		If schSCManager
			schService = OpenService_(schSCManager, @ServiceName, #GENERIC_READ)
			If schService
				If QueryServiceStatus_(schService, @sStatus)
					Result = sStatus\dwCurrentState
				EndIf
				CloseServiceHandle_(schService)
			EndIf
			CloseServiceHandle_(schSCManager)
		EndIf

		ProcedureReturn Result
	EndProcedure

EndModule
Last edited by HeX0R on Thu Dec 10, 2015 8:57 pm, edited 1 time in total.
User avatar
HeX0R
Addict
Addict
Posts: 992
Joined: Mon Sep 20, 2004 7:12 am
Location: Hell

Re: WinServices.pbi [Win] Module

Post by HeX0R »

updated example:

Code: Select all

EnableExplicit

InitSound()

#SERVICE_NAME = "THIS_IS_A_TEST"

XIncludeFile "Win_Services.pbi"

;Service won't work correctly with enabled debugger, so better make sure it is disabled.
DisableDebugger

Procedure.s GetErrorText(Error.l)
	Protected Buffer, Len, Result.s

	Len   = FormatMessage_(#FORMAT_MESSAGE_ALLOCATE_BUFFER | #FORMAT_MESSAGE_FROM_SYSTEM, 0, Error, 0, @Buffer, 0, 0)
	If Len
		Result = PeekS(Buffer, Len - 2)
		LocalFree_(Buffer)
	EndIf

	ProcedureReturn Result
EndProcedure

Procedure CheckButtons(State)
	Protected i

	Dim ButtonStates.i(4)
	For i = 0 To 3
		ButtonStates(i) = 1
	Next i
	Select State
		Case 1 ;Service Stopped, so enable Startbutton
			ButtonStates(2) = 0
		Case 4 ;Service Running, so enable Stop- and Pausebutton
			ButtonStates(0) = 0
			ButtonStates(3) = 0
		Case 7 ;Service Paused, enable Continuebutton
			ButtonStates(1) = 0
	EndSelect
	For i = 0 To 3
		DisableGadget(2 + i, ButtonStates(i))
	Next i

EndProcedure

Procedure main(IsService)
	Protected ServiceState, Err, i, k, Counter

	Dim Service_Message.s(7)
	Service_Message(0) = "No Service Installed"
	Service_Message(1) = "Service Stopped"
	Service_Message(2) = "Service Start Pending"
	Service_Message(3) = "Service Stop Pending"
	Service_Message(4) = "Service Running"
	Service_Message(5) = "Service Continue Pending"
	Service_Message(6) = "Service Pause Pending"
	Service_Message(7) = "Service Paused"

	;-Initial checking, what's going on

	ServiceState = WinService::GetServiceState(#SERVICE_NAME)   ;<- check, if service already exists and what state it is

	;If IsService = 1 we are definately called from the service, otherwise check what's up with the service-state
	If IsService = 0 And ServiceState = #SERVICE_START_PENDING ;<- Start_Pending means, we should now start with our service
		If WinService::StartRunning(#SERVICE_NAME, @main()) ;<- start the service mode. The procedure main() will get called again with IsService = #True
			;we will come here, when service has been stopped
			End
		EndIf
	EndIf

	If IsService
		OpenWindow(0, 5, 5, 305, 300, "Test", #PB_Window_SystemMenu | #PB_Window_Invisible)
		;#PB_Window_Invisible is not really necessary as long as we don't use the flag #SERVICE_INTERACTIVE_PROCESS when creating the service
		CatchSound(0, ?Sound) ;<- we only need the sound when running as service
	Else
		OpenWindow(0, 5, 5, 305, 300, "Test", #PB_Window_SystemMenu)
	EndIf
	EditorGadget(0, 5, 5, 295, 150, #PB_Editor_ReadOnly)
	ButtonGadget(1, 93, 165, 120, 24, "Install Service")
	ButtonGadget(2, 5, 195, 70, 22, "Pause")
	ButtonGadget(3, 80, 195, 70, 22, "Resume")
	ButtonGadget(4, 155, 195, 70, 22, "Start")
	ButtonGadget(5, 230, 195, 70, 22, "Stop")

	CreateStatusBar(0, WindowID(0))
	AddStatusBarField(#PB_Ignore)

	AddWindowTimer(0, 0, 500)

	If ServiceState <> 0
		SetGadgetText(1, "Remove Service")
	EndIf
	StatusBarText(0, 0, Service_Message(ServiceState))
	CheckButtons(ServiceState)

	Repeat
		Select WaitWindowEvent()
			Case #PB_Event_CloseWindow
				Break
			Case #PB_Event_Timer
				Select EventTimer()
					Case 0
						;Check State of Service
						k = WinService::GetServiceState(#SERVICE_NAME)
						If k <> ServiceState
							StatusBarText(0, 0, Service_Message(k))
							ServiceState = k
							CheckButtons(ServiceState)
						EndIf
						If IsService
							Counter + 1
							If Counter > 9
								;Beep any 5 Seconds, so you know, the service is running
								;(Beep_ and MessageBeep_ won't work inside services! [well... at least not in Win7])
								PlaySound(0)
								Counter = 0
							EndIf
						EndIf
				EndSelect
			Case #PB_Event_Gadget
				Select EventGadget()
					Case 1 ;install/uninstall
						If GetGadgetText(1) = "Remove Service"
							If WinService::RemoveService(#SERVICE_NAME)
								SetGadgetText(1, "Install Service")
								AddGadgetItem(0, -1, "Service 'Test App' removed!")
							Else
								Err = GetLastError_()
								AddGadgetItem(0, -1, "Error, while trying to remove the service:")
								If Err = #ERROR_ACCESS_DENIED
									AddGadgetItem(0, -1, "You don't have enough rights, try to start as admin.")
								Else
									AddGadgetItem(0, -1, GetErrorText(Err))
								EndIf
							EndIf
						Else
							If WinService::InstallService(#SERVICE_NAME, "TestApp", ProgramFilename(), "Dies ist eine TestApp")
								If WinService::GrantAccess(#SERVICE_NAME, UserName()) = 0
									Err = GetLastError_()
									AddGadgetItem(0, -1, GetErrorText(Err))
								EndIf
								SetGadgetText(1, "Remove Service")
								AddGadgetItem(0, -1, "Service 'Test App' installed!")
							Else
								Err = GetLastError_()
								AddGadgetItem(0, -1, "Error, while trying to install the service:")
								If Err = #ERROR_ACCESS_DENIED
									AddGadgetItem(0, -1, "You don't have enough rights, try to start as admin.")
								Else
									AddGadgetItem(0, -1, GetErrorText(Err))
								EndIf
							EndIf
						EndIf
					Case 2 ;pause
						If WinService::PauseService(#SERVICE_NAME) = 0
							Err = GetLastError_()
							AddGadgetItem(0, -1, GetErrorText(Err))
						EndIf
					Case 3 ;resume
						If WinService::ResumeService(#SERVICE_NAME) = 0
							Err = GetLastError_()
							AddGadgetItem(0, -1, GetErrorText(Err))
						EndIf
					Case 4 ;start
						If WinService::StartService(#SERVICE_NAME) = 0
							Err = GetLastError_()
							AddGadgetItem(0, -1, GetErrorText(Err))
						EndIf
					Case 5 ;stop
						If WinService::StopService(#SERVICE_NAME) = 0
							Err = GetLastError_()
							AddGadgetItem(0, -1, GetErrorText(Err))
						EndIf
				EndSelect
		EndSelect
	ForEver
EndProcedure


main(0)
End

DataSection
	Sound:
	;a little beep sound
	Data.l $46464952, $00000D12, $45564157, $20746D66, $00000010, $00010001, $00002B11, $00002B11
	Data.l $00080001, $61746164, $00000CED, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F807F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F80, $7F7F8080, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F708281, $AF5F709E
	Data.l $C07F43A0, $88BD5F60, $60C08F45, $4B80B767, $6F60C097, $9F4F80B6, $C06F60C0, $A09F4F80
	Data.l $70C06F50, $50A09F4F, $4F70C077, $7F50A09F, $AB5770C0, $C07F4AA0, $90AF5770, $60C07F4A
	Data.l $4B90AF5F, $5F60C07F, $7F4B90AF, $B36760C0, $C08F4D88, $80B56760, $60C0974F, $4F80B56F
	Data.l $6F60A89F, $9F4F80B5, $C06F60A0, $A09F4F78, $70C07750, $50A09F57, $5770C07F, $7F50A0A7
	Data.l $AF5B70C0, $C07F4D90, $90AF5F68, $60C07F4D, $4F90AF5F, $6760C07F, $8F4F88AF, $B36760C0
	Data.l $A8974F80, $80B36F60, $60A89F4F, $5380B46F, $6F60A09F, $9F5780B4, $B27750A0, $A09F5780
	Data.l $70C07F50, $50A09F57, $5F70C07F, $7F5090AB, $AF5F68C0, $C07F5090, $90AF6760, $60A87F51
	Data.l $5180AF67, $6760A88F, $975380AF, $B26F60A8, $A0975380, $80B26F60, $60A09F57, $5780B16F
	Data.l $7760A09F, $9F5780B0, $B07F50A0, $A09F5B80, $70B07F50, $5190A75F, $5F68B07F, $7F5190AB
	Data.l $AF6760B0, $A87F5190, $88AF6760, $60A87F53, $5380AF6F, $6F60A88F, $975380AF, $B06F60A0
	Data.l $A09F5780, $80B06F60, $60A09F57, $5780B077, $7F52A09F, $9F5F80B0, $B07F5298, $90A75F70
	Data.l $68B07F51, $5290AB5F, $6760A87F, $7F5390AD, $AF6760A8, $A87F5388, $80AF6F60, $60A48F53
	Data.l $5780AF6F, $6F60A097, $9F5780AF, $AE6F60A0, $A09F5780, $80B07760, $54A09F5B, $5F80B07F
	Data.l $7F52909F, $9F5F70AC, $AC7F5290, $90A76368, $64A87F53, $5390AB67, $6760A87F, $7F5380AD
	Data.l $AF6F60A8, $A08F5580, $80AF6F60, $60A09757, $5780AF6F, $7760A09F, $9F5780AE, $AE7760A0
	Data.l $A09F5B80, $80AC7F60, $54909F5F, $5F70AC7F, $7F53909F, $A76368A8, $A87F5390, $90AB6768
	Data.l $60A87F53, $5580AD67, $6F60A87F, $8F5580AD, $AE6F60A0, $A0975780, $80AE6F60, $60A09F57
	Data.l $5780AC77, $7B60A09F, $9F5B80AC, $AC7F60A0, $909F5F80, $70AC7F54, $53909F5F, $6768A87F
	Data.l $7F5390A7, $AB6764A8, $A87F5388, $80AB6760, $60A07F55, $5780AB6F, $6F60A08F, $975780AD
	Data.l $AD6F60A0, $A09B5780, $80AC7760, $60A09F5B, $5F80AC7B, $7F60989F, $9F5F80AC, $AA7F5490
	Data.l $909F5F70, $68A87F54, $5490A763, $6768A87F, $7F5588A7, $AB6760A8, $A07F5580, $80AB6F60
	Data.l $60A08F57, $5780AB6F, $6F60A097, $975780AC, $967F60A0, $7C887778, $7F78847F, $877B7A88
	Data.l $80837C80, $7F7E817F, $827E7E82, $80817D80, $7F807F7E, $7F7F7F7F, $7F7F7F7F, $7F7F807F
	Data.l $7F7F807F, $7F7F7F80, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7E7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7E
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7E7F7F, $7F7F7E7F, $7F7F7E7F, $7F7F7F7E, $7F7F7F7F, $7F7F7F7F
	Data.l $7E7E7F7F, $7F7E7F7F, $7F7F7F7F, $7F7F7E7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7E7F7F7E, $7E7F7F7F, $7F7E7F7F, $7F7E7F7F, $7F7F7E7F
	Data.l $7F7F7E7F, $7F7F7F7E, $7E7F7F7E, $7E7F7F7F, $7F7E7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7E7F
	Data.l $7E7F7F7E, $7E7F7F7E, $7E7E7F7F, $7F7E7F7F, $7F7E7E7F, $7F7F7E7E, $7E7F7F7E, $7E7E7F7E
	Data.l $7F7E7F7F, $7F7E7E7F, $7F7E7E7F, $7F7F7E7E, $7E7F7F7E, $7E7F7F7E, $7E7E7F7E, $7F7E7F7F
	Data.l $7F7E7E7F, $7F7F7E7F, $7F7F7E7E, $7E7F7F7E, $7E7F7F7E, $7F7E7F7F, $7F7E7E7F, $7F7F7E7F
	Data.l $7F7F7E7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7E7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7E7F7F7E, $7E7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7E7F, $7F7F7F7F, $7E7F7F7E
	Data.l $7E7F7F7F, $7F7E7F7F, $7F7E7E7F, $7F7F7E7F, $7F7F7F7E, $7F7F7F7E, $7E7F7F7F, $7F7F7F7F
	Data.l $7F7E7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7E7F7F7F, $7F7F7F7F, $7F7E7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $74817F7F, $6380987F, $7F50909F, $AD5F68C0, $A87F5190, $80AB6760, $60A07F57
	Data.l $5780A76F, $6F60A07F, $8F5780AA, $AA6F60A0, $A0975780, $80AA6F60, $60A09B57, $5B80AA77
	Data.l $7F60989F, $9F5F80AA, $A87F6090, $909F5F70, $70A87F54, $55909F63, $6768A87F, $7F5588A7
	Data.l $A76760A4, $A07F5580, $80AB6F60, $60A08F57, $5780AB6F, $6F60A097, $975780AB, $AA6F60A0
	Data.l $A09F5780, $80AC7760, $60989F5B, $5F80AA7F, $7F54909F, $9F5F70A8, $A87F5490, $90A76368
	Data.l $68A87F54, $5588A767, $6760A47F, $7F5580AB, $AB6F60A0, $A08F5780, $80AB6F60, $60A09757
	Data.l $5780AB6F, $7760A09B, $9F5B80AC, $AA7760A0, $909F5B80, $80A87F60, $54909F5F, $5F70A87F
	Data.l $7F54909F, $A76768A8, $A87F5590, $88A76764, $60A47F55, $5580AB67, $6F60A07F, $8F5780AB
	Data.l $AB6F60A0, $A0975780, $80AB6F60, $60A09757, $5B80AC77, $7F60A09F, $9F5F80AA, $A87F6098
	Data.l $909F5F80, $70A87F54, $55909F63, $6768A87F, $7F5590A7, $A76768A8, $A47F5588, $80AB6760
	Data.l $60A07F57, $5780AB6F, $6F60A08F, $975780AB, $AB6F60A0, $A09B5780, $80AA7760, $60A09F5B
	Data.l $5F80AA7F, $7F60909F, $9F5F80A8, $A87F5490, $909F6370, $68A87F55, $5590A767, $6760A87F
	Data.l $7F5580A7, $AB6B60A4, $A08F5780, $80AB6F60, $60A08F57, $5780AB6F, $6F60A097, $9B5780AB
	Data.l $AA7760A0, $989F5B80, $80AA7F60, $60909F5F, $5F70A87F, $7F55909F, $9F6370A8, $A87F5590
	Data.l $88A76768, $60A47F55, $5588A767, $6F60A47F, $8F5780AB, $AB6F60A0, $A0975780, $80AB6F60
	Data.l $60A09757, $5780AA6F, $7760A09B, $9F5B80AA, $AA7F6098, $909F5F80, $70A87F60, $54909F5F
	Data.l $6370A87F, $7F55909F, $A76768A8, $A87F5588, $80A76760, $60A07F57, $5780AB6F, $6F60A08F
	Data.l $975780AB, $AB6F60A0, $A0975780, $80AA6F60, $60A09B5B, $5B80AA77, $7F60989F, $9F5F80AA
	Data.l $A87F6090, $909F5F70, $70A87F54, $55909F63, $6768A87F, $7F5588A7, $A76760A4, $A07F5580
	Data.l $80AB6B60, $60A08F57, $5780AB6F, $6F60A097, $975780AB, $AA7760A0, $A09F5B80, $80AA7760
	Data.l $60989F5B, $5F80AA7F, $7F60909F, $9F6370A8, $A87F5590, $909F6768, $68A87F55, $5588A767
	Data.l $6760A47F, $7F5780A7, $AB6F60A0, $A08F5780, $80AB6F60, $60A09757, $5780AB6F, $7F60A097
	Data.l $88777894, $78847F7C, $7B7A887F, $827C8086, $7E817E80, $7E7E827F, $817D8082, $807F7E80
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F807F7E, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7E7F7F7F, $7E7F7F7F, $7F7E7F7F, $7F7F7F7F, $7F7F7E7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7E7F7F7E, $7E7E7F7F, $7F7E7F7F
	Data.l $7F7E7F7F, $7F7F7E7F, $7F7F7E7F, $7F7F7F7E, $7E7F7F7E, $7E7E7F7F, $7F7E7F7F, $7F7E7E7F
	Data.l $7F7F7E7F, $7E7F7E7E, $7E7F7F7E, $7F7E7F7F, $7F7E7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7E
	Data.l $7F7F7F7F, $7E7F7F7F, $7F7E7F7F, $7F7E7F7F, $7F7F7E7F, $7F7F7E7F, $7F7F7F7E, $7F7F7F7E
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7E7F7F
	Data.l $7F7F7E7F, $7F7F7E7F, $7F7F7F7E, $7E7F7F7E, $7F7F7F7F, $7F7E7F7F, $7F7F7F7F, $7F7F7E7F
	Data.l $7F7F7F7E, $7E7F7F7E, $7E7F7F7F, $7F7E7F7F, $7F7F7F7F, $7F7E7E7F, $7F7F7F7F, $7F7F7F7E
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7E7F7F7E, $7E7F7F7E, $7E7E7F7F, $7F7E7F7F, $7F7E7E7F
	Data.l $7F7F7E7F, $7F7F7F7E, $7E7F7F7E, $7F7F7F7F, $7F7E7F7F, $7F7F7F7F, $7F7F7E7F, $7F7F7E7F
	Data.l $7F7F7F7E, $7E7F7F7E, $7E7E7F7F, $7F7E7F7F, $7F7F7E7F, $7F7F7E7F, $7F7F7F7E, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7E7F, $7F7F7F7F, $7F7F7F7E, $7E7F7F7E, $7E7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7E7F, $7F7F7F7F, $7F7F7F7E, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.b $7F, $00
EndDataSection
User avatar
ts-soft
Always Here
Always Here
Posts: 5756
Joined: Thu Jun 24, 2004 2:44 pm
Location: Berlin - Germany

Re: WinServices.pbi [Win] Module

Post by ts-soft »

Image thx for sharing
PureBasic 5.73 | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.
Image
User avatar
NoahPhense
Addict
Addict
Posts: 1999
Joined: Thu Oct 16, 2003 8:30 pm
Location: North Florida

Re: WinServices.pbi [Win] Module

Post by NoahPhense »

Nice!
User avatar
HAnil
User
User
Posts: 87
Joined: Thu Feb 26, 2004 5:42 pm
Location: 28:58E 41:01N

Re: WinServices.pbi [Win] Module

Post by HAnil »

Hello HeX0R

when upgrading PureBasic to beta15, WinServices.pbi is not compiled and compiler broken.
why can not work ?

Regards,
Anil
PureBasic v5.22 LTS & Mac & Windows8
User avatar
ts-soft
Always Here
Always Here
Posts: 5756
Joined: Thu Jun 24, 2004 2:44 pm
Location: Berlin - Germany

Re: WinServices.pbi [Win] Module

Post by ts-soft »

Confirmed, crashes with Beta 15!

// edit
Bug reported: http://www.purebasic.fr/english/viewtop ... 98#p423298
PureBasic 5.73 | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.
Image
User avatar
skywalk
Addict
Addict
Posts: 3999
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: WinServices.pbi [Win] Module

Post by skywalk »

Thanks HeX0R, really useful :)
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
User avatar
NoahPhense
Addict
Addict
Posts: 1999
Joined: Thu Oct 16, 2003 8:30 pm
Location: North Florida

Re: WinServices.pbi [Win] Module

Post by NoahPhense »

Badas$.. nice modules!

- np
mikejs
Enthusiast
Enthusiast
Posts: 166
Joined: Thu Oct 21, 2010 9:46 pm

Re: WinServices.pbi [Win] Module

Post by mikejs »

Been using this for a while, and I think I've found a (minor) bug in CtrlHandler:

Code: Select all

   Procedure CtrlHandler(controlCode.l)
      Protected currentState, success, nopThread

      ;Controlhandler, which gets called, whenever a service state has been changed.
      ;If an optional notify-procedure has been set, it will also be called

      With ServiceGlobals
         Select controlCode
            Case #SERVICE_CONTROL_STOP
               currentState  = #SERVICE_STOP_PENDING
               ;Tell the SCM what's happening
               SendStatus(#SERVICE_STOP_PENDING, #NO_ERROR, 0, 1, 5000)
               ; Changed on 27.09.2005 by Peter Tübben (aka Kiffi)

               ;First notify, otherwise it will be to late...
               If \NotifyProc
                  \NotifyProc(controlCode)
               EndIf
               SignalSemaphore(\Semaphore)
               ProcedureReturn
            Case #SERVICE_CONTROL_PAUSE
               SendStatus(#SERVICE_PAUSE_PENDING, #NO_ERROR, 0, 1, 1000)
               PauseThread(\ThreadID)
               currentState  = #SERVICE_PAUSED
            Case #SERVICE_CONTROL_CONTINUE
               SendStatus(#SERVICE_CONTINUE_PENDING, #NO_ERROR, 0, 1, 1000)
               ResumeThread(\ThreadID)
               currentState  = #SERVICE_RUNNING
            Case #SERVICE_CONTROL_INTERROGATE
               ; it will fall to bottom and send status
               ;Could do cleanup here but it must be very quick.
            Case #SERVICE_CONTROL_SHUTDOWN
               ;The service is notified when system
               ;shutdown occurs.
               ;Do nothing on shutdown.
         EndSelect

         SendStatus(currentState, #NO_ERROR, 0, 0, 0)
         If \NotifyProc
            \NotifyProc(controlCode)
         EndIf
      EndWith

   EndProcedure
What happens there is that currentState is set to various things depending on the control code, but if the control code is #SERVICE_CONTROL_INTERROGATE, it doesn't get set at all. In which case the SendStatus at the end passes 0 in the currentState variable.

0 is not a valid current state, and this results in messages in eventviewer of the form "The [whatever] service has reported an invalid current state 0."

Fix is fairly simple - add a line to populate the currentState variable with the current state of the service at start of the proc:

Code: Select all

   Procedure CtrlHandler(controlCode.l)
      Protected currentState, success, nopThread

      ;Controlhandler, which gets called, whenever a service state has been changed.
      ;If an optional notify-procedure has been set, it will also be called

      ; Populate currentState with the current state of the service
      currentState=GetServiceState(\ServiceName)

      With ServiceGlobals
         Select controlCode
            Case #SERVICE_CONTROL_STOP
               currentState  = #SERVICE_STOP_PENDING
               ;Tell the SCM what's happening
               SendStatus(#SERVICE_STOP_PENDING, #NO_ERROR, 0, 1, 5000)
               ; Changed on 27.09.2005 by Peter Tübben (aka Kiffi)

               ;First notify, otherwise it will be to late...
               If \NotifyProc
                  \NotifyProc(controlCode)
               EndIf
               SignalSemaphore(\Semaphore)
               ProcedureReturn
            Case #SERVICE_CONTROL_PAUSE
               SendStatus(#SERVICE_PAUSE_PENDING, #NO_ERROR, 0, 1, 1000)
               PauseThread(\ThreadID)
               currentState  = #SERVICE_PAUSED
            Case #SERVICE_CONTROL_CONTINUE
               SendStatus(#SERVICE_CONTINUE_PENDING, #NO_ERROR, 0, 1, 1000)
               ResumeThread(\ThreadID)
               currentState  = #SERVICE_RUNNING
            Case #SERVICE_CONTROL_INTERROGATE
               ; it will fall to bottom and send status
               ;Could do cleanup here but it must be very quick.
            Case #SERVICE_CONTROL_SHUTDOWN
               ;The service is notified when system
               ;shutdown occurs.
               ;Do nothing on shutdown.
         EndSelect

         SendStatus(currentState, #NO_ERROR, 0, 0, 0)
         If \NotifyProc
            \NotifyProc(controlCode)
         EndIf
      EndWith

   EndProcedure
Then, if the service is running, the normal interrogation will report the correct state.
User avatar
HeX0R
Addict
Addict
Posts: 992
Joined: Mon Sep 20, 2004 7:12 am
Location: Hell

Re: WinServices.pbi [Win] Module

Post by HeX0R »

Yes, you are right, thanks for the fix, even if it is not 100% correct, or did you try to use it like this? ;)

I've fixed the original code.
mikejs
Enthusiast
Enthusiast
Posts: 166
Joined: Thu Oct 21, 2010 9:46 pm

Re: WinServices.pbi [Win] Module

Post by mikejs »

HeX0R wrote:Yes, you are right, thanks for the fix, even if it is not 100% correct, or did you try to use it like this? ;)

I've fixed the original code.
Hmm, yes, that's not going to work is it. Exercise left for the reader... 8)

I copied (and mis-pasted) just those two lines because my version has some other changes in it - I needed a service that could respond to #SERVICE_CONTROL_PRESHUTDOWN events, which means differences in the dwControlsAccepted field, and the use of RegisterServiceCtrlHandlerEx (which needs prototyping and loading from advapi32.dll) rather than RegisterServiceCtrlHandler. I have this pretty much working, but I'm still tidying it up.
Thorium
Addict
Addict
Posts: 1271
Joined: Sat Aug 15, 2009 6:59 pm

Re: WinServices.pbi [Win] Module

Post by Thorium »

I have a win service related question, not PB specific, but maybe someone knows about it.
I want to to run a server program on our internal server. Our admin told me he want's it to be a service, so he has better control over it. So i used your code and it works without problems on my machine. However on the server, which is a windows server, the service starts and then windows immediately shuts it down. Windows displays a message that services which are not used by any ressource will be terminated. Or something similar. The message is in german, so this is not the exact wording.

Our admin does not know why this happens and i dont know as well.
Anyone know what mechanic of windows is shuting the service down and how to tell windows that the service is needed to be running?
User avatar
HeX0R
Addict
Addict
Posts: 992
Joined: Mon Sep 20, 2004 7:12 am
Location: Hell

Re: WinServices.pbi [Win] Module

Post by HeX0R »

Did you already see this:
http://www.purebasic.fr/english/viewtop ... 01#p455201

Also my last sentence:
By default the users don't have the right to run as service, you need to add your user in the Local Security Policy (User Rights Assignment/Log on as a service).
If nothing helps, could your admin provide the win log to see what exactly is happening?
User avatar
RichAlgeni
Addict
Addict
Posts: 914
Joined: Wed Sep 22, 2010 1:50 am
Location: Bradenton, FL

Re: WinServices.pbi [Win] Module

Post by RichAlgeni »

I had a similar issue a couple of years ago. I found that the Registry code I had modified was trying to open the registry in read/write mode. This worked fine on my machine, but would exit suddenly on my client's server. I changed the registry code so that it opened the registry as read only, and the service then worked fine.
Thorium
Addict
Addict
Posts: 1271
Joined: Sat Aug 15, 2009 6:59 pm

Re: WinServices.pbi [Win] Module

Post by Thorium »

HeX0R wrote: Also my last sentence:
By default the users don't have the right to run as service, you need to add your user in the Local Security Policy (User Rights Assignment/Log on as a service).
I will tell him early next year.
I think we installed it under system user. Maybe we need to install it under a user and set the rights as you wrote.
Post Reply