Services

Just starting out? Need help? Post your questions and find answers here.
Armoured
Enthusiast
Enthusiast
Posts: 365
Joined: Mon Jan 26, 2004 11:39 am
Location: ITALY
Contact:

Services

Post by Armoured »

Hi :)
How I can start, stop and pause an existing service without the pbosl libraries?


Thanks
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

You can use WMI via COMate :

Code: Select all

;/////////////////////////////////////////////////////////////////////////////////
;***COMate***  COM automation through iDispatch.
;*===========
;*
;*WMI demo - services.
;/////////////////////////////////////////////////////////////////////////////////

IncludePath "..\..\"
XIncludeFile "COMate.pbi"

Enumeration
  #StopService
  #PauseService
  #StartService
EndEnumeration


;Returns #True if successful.
Procedure Set_Service(serviceName$, action = #StopService)
  Protected result, strComputer.s, objWMIService.COMateObject, service.COMateObject 
  Protected colServices.COMateEnumObject 
  strComputer = "." 
  objWMIService = COMate_GetObject("winmgmts:\\" + strComputer + "\root\cimv2", "") 
  If objWMIService 
    colServices = objWMIService\CreateEnumeration("ExecQuery('Select * FROM Win32_Service WHERE Name = $0027" + serviceName$ + "$0027')") 
    If colServices
      service = colServices\GetNextObject() 
      If service
        Select action
          Case #StopService
            If SUCCEEDED(service\Invoke("StopService"))
              result = #True
            EndIf
          Case #PauseService
            If SUCCEEDED(service\Invoke("PauseService"))
              result = #True
            EndIf
          Case #StartService
            If SUCCEEDED(service\Invoke("StartService"))
              result = #True
            EndIf
        EndSelect
        service\Release() 
      EndIf 
      colServices\Release() 
    EndIf 
    objWMIService\Release()  
  EndIf 
  ProcedureReturn result
EndProcedure 

Set_Service("Apache2", #StartService)
Alternatively, you can also use 'Active Directory' (again with COMate), although the code would be very similar to the above.

Just out of curiosity, what's wrong with PBOSL ?
I may look like a mule, but I'm not a complete ass.
Armoured
Enthusiast
Enthusiast
Posts: 365
Joined: Mon Jan 26, 2004 11:39 am
Location: ITALY
Contact:

Post by Armoured »

Hi srod :)
srod wrote:You can use WMI via COMate :

Code: Select all

;/////////////////////////////////////////////////////////////////////////////////
;***COMate***  COM automation through iDispatch.
;*===========
;*
;*WMI demo - services.
;/////////////////////////////////////////////////////////////////////////////////

IncludePath "..\.."
XIncludeFile "COMate.pbi"

Enumeration
  #StopService
  #PauseService
  #StartService
EndEnumeration


;Returns #True if successful.
Procedure Set_Service(serviceName$, action = #StopService)
  Protected result, strComputer.s, objWMIService.COMateObject, service.COMateObject 
  Protected colServices.COMateEnumObject 
  strComputer = "." 
  objWMIService = COMate_GetObject("winmgmts:\" + strComputer + "\root\cimv2", "") 
  If objWMIService 
    colServices = objWMIService\CreateEnumeration("ExecQuery('Select * FROM Win32_Service WHERE Name = $0027" + serviceName$ + "$0027')") 
    If colServices
      service = colServices\GetNextObject() 
      If service
        Select action
          Case #StopService
            If SUCCEEDED(service\Invoke("StopService"))
              result = #True
            EndIf
          Case #PauseService
            If SUCCEEDED(service\Invoke("PauseService"))
              result = #True
            EndIf
          Case #StartService
            If SUCCEEDED(service\Invoke("StartService"))
              result = #True
            EndIf
        EndSelect
        service\Release() 
      EndIf 
      colServices\Release() 
    EndIf 
    objWMIService\Release()  
  EndIf 
  ProcedureReturn result
EndProcedure 

Set_Service("Apache2", #StartService)
Alternatively, you can also use 'Active Directory' (again with COMate), although the code would be very similar to the above.

Just out of curiosity, what's wrong with PBOSL ?
PBOSL works well but I want to reduce the dependence of my work from external libraries.
There isn't any api to control a service?
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

There isn't any api to control a service?
Sure there is! :) You have to talk directly to the service control manager.

Why not download the PBOSL source and, assuming the services lib is in PB form, use it directly.
I may look like a mule, but I'm not a complete ass.
thefool
Always Here
Always Here
Posts: 5875
Joined: Sat Aug 30, 2003 5:58 pm
Location: Denmark

Post by thefool »

Or use "piped" calls to "NET". Like "net start service". Its a bit uglier than the rest, though, but an option :)
afriend
User
User
Posts: 20
Joined: Thu Aug 09, 2007 5:47 am
Location: Melbourne, Australia

Services

Post by afriend »

Try using MicroSofts Netsvc.exe. This program can be run using PureBasic's runprogram. You can download the file from MicroSoft.

The MS file can be used on a local host or on a computer connected to the network.

The MS file has many advantages in a network and would be worthwhile considering.
maw

Post by maw »

It's very easy to control services using API actually. The following snippet should get you on your way:

Code: Select all

status.SERVICE_STATUS
servicename$ = "Spooler"
hmanager = OpenSCManager_(0, 0, #SC_MANAGER_ALL_ACCESS)
hservice = OpenService_(hmanager, @servicename$, #SERVICE_ALL_ACCESS)
ControlService_(hservice, #SERVICE_CONTROL_INTERROGATE, @status)
If status\dwCurrentState = #SERVICE_RUNNING 
	ControlService_(hservice, #SERVICE_CONTROL_STOP, @status)
ElseIf status\dwCurrentState = #SERVICE_STOPPED
	StartService_(hservice, 0, 0)
EndIf
CloseServiceHandle_(hservice)
CloseServiceHandle_(hmanager)
Please note that the above snippet will stop the print spooler service if it's running and start it if it's not running.
swhite
Addict
Addict
Posts: 805
Joined: Thu May 21, 2009 6:56 pm

Re: Windows Service Questions

Post by swhite »

maw wrote:It's very easy to control services using API actually. The following snippet should get you on your way:

Code: Select all

status.SERVICE_STATUS
servicename$ = "Spooler"
hmanager = OpenSCManager_(0, 0, #SC_MANAGER_ALL_ACCESS)
hservice = OpenService_(hmanager, @servicename$, #SERVICE_ALL_ACCESS)
ControlService_(hservice, #SERVICE_CONTROL_INTERROGATE, @status)
If status\dwCurrentState = #SERVICE_RUNNING 
	ControlService_(hservice, #SERVICE_CONTROL_STOP, @status)
ElseIf status\dwCurrentState = #SERVICE_STOPPED
	StartService_(hservice, 0, 0)
EndIf
CloseServiceHandle_(hservice)
CloseServiceHandle_(hmanager)
Please note that the above snippet will stop the print spooler service if it's running and start it if it's not running.
Since I am new to PB can someone explain what I am missing in my knowledge of PB. I see this code works but fail to understand how PB knows what to do with OpenScManager_(), ControlService_() etc.
Also what is the meaning of status.SERVICE_STATUS? It looks like a type but why does PB not complain that it does not know what it is?

Thanks
Simon
Simon White
dCipher Computing
swhite
Addict
Addict
Posts: 805
Joined: Thu May 21, 2009 6:56 pm

Re: Services

Post by swhite »

PB will instantly recognize Win API constants if you preceed them with the "#" (pound) character, just as it instantly recognizes Win API procedures if you trail them with a "_" (underscord) character.
Okay so I found part of the answer in another message but I do not know where in the documentation this is mentioned.

Simon
Simon White
dCipher Computing
User avatar
spikey
Enthusiast
Enthusiast
Posts: 778
Joined: Wed Sep 22, 2010 1:17 pm
Location: United Kingdom

Re: Services

Post by spikey »

There isn't a separate section on supporting the Windows API in the PureBasic help - if that's what you mean.
Although there are a couple of discrete references to the existance of this feature in the help and on the website too.

Lots of Windows API stuff is supported directly in PB :
by adding the _ character to the end of the function call before you supply arguments.
by adding # to the front of constants.
Lots of types are already declared for you too - which is why the demo code works.

Its just one of the things the PB developers do to spoil us rotten...

The structure viewer (in the tools menu) has a tab marked "Structures" - which includes all those from the Windows API defined in PureBasic. Similarly the "Constants" panel shows all of those available too.

If you have Autocomplete switched on in Preferences then the autocomplete popup will include constants and function calls from the Windows API too.

You can also integrate the Microsoft API documentation into the PureBasic IDE. There is an article in the online help under "The PureBasic IDE/Getting Help" - read the section "Quick access to Windows API help". You have to download some extra files to get this to work though as they aren't included with the PureBasic installation download.

Alternatively in his forum article http://forums.purebasic.com/german/viewtopic.php?t=4566 ts-soft gives a nice little tool you can build to plug into the IDE which uses Google as an intermediary to automate keyword lookups from the PB IDE directly to the MSDN website. Just change the reference in the string at the end from google.de to use your most local google homepage.
swhite
Addict
Addict
Posts: 805
Joined: Thu May 21, 2009 6:56 pm

Re: Services

Post by swhite »

Thanks Spikey for this useful information. It would also be nice if this was incorporated into the PB help file.

Simon
Simon White
dCipher Computing
Dude
Addict
Addict
Posts: 1907
Joined: Mon Feb 16, 2015 2:49 pm

Re:

Post by Dude »

Code: Select all

status.SERVICE_STATUS
servicename$ = "Fax"
hmanager = OpenSCManager_(0, 0, #SC_MANAGER_ALL_ACCESS)
hservice = OpenService_(hmanager, @servicename$, #SERVICE_ALL_ACCESS)
ControlService_(hservice, #SERVICE_CONTROL_INTERROGATE, @status)
If status\dwCurrentState = #SERVICE_RUNNING 
	ControlService_(hservice, #SERVICE_CONTROL_STOP, @status)
ElseIf status\dwCurrentState = #SERVICE_STOPPED
	StartService_(hservice, 0, 0)
EndIf
CloseServiceHandle_(hservice)
CloseServiceHandle_(hmanager)
I'm trying to use this to toggle the Fax service, and it worked ONCE (it successfully changed it from Stopped to Started, per the Task Manager); but now it doesn't work at all. Yes, I'm running it as admin, and no, it's not because of my anti-virus. Why would it only do it once?

[Edit] Hmm, even using "net start fax" from an elevated command prompt doesn't work; and I can't start it with Task Manager either. :shock: So it's not the code above causing it. Sorry. But why can't I start/stop services as admin all of a sudden?
User avatar
JHPJHP
Addict
Addict
Posts: 2271
Joined: Sat Oct 09, 2010 3:47 am

Re: Services

Post by JHPJHP »

Hi Dude,

What happens when you try stopping / starting another service?
- see Services, Stuff & Shellhook
-- \Services\StartStopService.pb ( WindowsServices.pbi )

NB*: Various parts of the package can be downloaded separately.

If you're not investing in yourself, you're falling behind.

My PureBasic StuffFREE STUFF, Scripts & Programs.
My PureBasic Forum ➤ Questions, Requests & Comments.
Dude
Addict
Addict
Posts: 1907
Joined: Mon Feb 16, 2015 2:49 pm

Re: Services

Post by Dude »

JHPJHP, your code doesn't start the Fax service, or any other stopped service that I tried, either. I didn't think it would, because like I mentioned above: even the "net" DOS command and Task Manager won't start them.
Post Reply