Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

[WinServ] Start, Stop or Query a windows service (WinAPI)


  • Please log in to reply
19 replies to this topic
Hardeep
  • Members
  • 87 posts
  • Last active: Sep 12 2007 06:40 PM
  • Joined: 02 Jul 2006
WinServ function can be used to start, stop or query(running status) a windows service on local or a remote computer. Dialogs provide visual feedback when starting/stopping a service or when an error occurs. Usage documentation is included in the library.

Download WinServ.ahk v1.0 (This file can be directly copied to the library.)

Posted Image

Example Usage:
Caution: Executing the following code will start/stop the specified services on your system.

;Start the Task Scheduler service by using its Service Name
WinServ("Schedule", True) ;Returns True if started successfully.

;Stop the Task Scheduler service by using its Display Name
WinServ("Task Scheduler", False) ;Returns True if stopped successfully.

;Start the Windows Time service silently
WinServ("Windows time", True, True) ;No popups

;Start the Task Scheduler service on remote computer name ZOMBIE
WinServ("Schedule", True, False, "ZOMBIE") ;Returns True if started successfully.

;Check if the WebClient service is running
If WinServ("WebClient")
{	MsgBox, WebClient is up & running
	;Do Something
}

;Toggle the DNS Client service
WinServ("DNS Client", WinServ("DNS Client") ? False : True)


n-l-i-d
  • Guests
  • Last active:
  • Joined: --
Very nice! 8)

corrupt
  • Members
  • 2558 posts
  • Last active: Nov 01 2014 03:23 PM
  • Joined: 29 Dec 2004
Cool 8) . Thanks :)

Hardeep
  • Members
  • 87 posts
  • Last active: Sep 12 2007 06:40 PM
  • Joined: 02 Jul 2006
Thanks guys! Any feedback is highly appreciated.

Will share some more useful functions soon...

PhiLho
  • Moderators
  • 6850 posts
  • Last active: Jan 02 2012 10:09 PM
  • Joined: 27 Dec 2005
I really appreciated this function!
I come back from holidays, my boss ask me to automatically install a Tomcat Java application, which needs to stop and start the Apache Tomcat service.
I search the forum... and here is your script!
Very handy.

The only problem is that you use the Progress command unconditionally, just to display some messages. It ruins my larger script which has a global progress bar (do this, start service, do that).
I suggest to use a GUI instead: more work, but it would better fit as function.
Posted Image vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2")

Hardeep
  • Members
  • 87 posts
  • Last active: Sep 12 2007 06:40 PM
  • Joined: 02 Jul 2006

The only problem is that you use the Progress command unconditionally, just to display some messages. It ruins my larger script which has a global progress bar (do this, start service, do that).
I suggest to use a GUI instead: more work, but it would better fit as function.


Thanks for bringing it to my notice. I have changed the Progress command to use 10 (max value) as the window number. I hope this will help avoid any progress window conflicts since I highly doubt a user would be displaying 10 progress windows at the same time.

I completely agree that using a GUI for this purpose would be more elegant and will implement it when I get time...right now I am too busy with my work.

WhoAmIAgain?
  • Guests
  • Last active:
  • Joined: --
Thanks for this function, I have a antivirus that may work great but it uses 3 processes and a good chunk of my memory. Using this function I made a quick .exe that turns on everything it needs to run, or in 1 click jump through all the hoops it takes to disable the thing.


Why does Avira demand a 10 MB process just to check for updates once a day? *shakes his head*

Gauss
  • Members
  • 203 posts
  • Last active: Jan 27 2012 12:49 PM
  • Joined: 10 Sep 2009
Thanks Hardeep
Very useful, is it possible to set the service status to disabled and manual too?

Edit:

I found it out
run, sc config Service_Name start= demand
run, net start Service_Name

* auto--a service automatically started at boot time, even if no user logs on
* boot--a device driver loaded by the boot loader
* demand--a service that must be manually started (the default)
* disabled--a service that can't be started
* system--a service started during kernel initialization



The only thing is that it displays command prompt window, any idea how to do the same without having to see that window?

jasonwills
  • Guests
  • Last active:
  • Joined: --
This is a great function - thankyou for it.

i have used the following code:

^!I::
If WinServ("ServiceName")
{
WinServ("ServiceName", False, True)
}
Else
{
WinServ("ServiceName", True, True)
}

this works great - however, i would like at the press of Ctrl + Alt+ I to toggle multiple services not just "ServiceName" anyone know of an easy way of doing this, thanks for any help in advance.

Jason

Deep-Silence
  • Members
  • 89 posts
  • Last active: May 03 2015 05:54 AM
  • Joined: 24 Apr 2009
Try this code to hide the commandline window

Run, %comspec% /c "net start Service_Name",, Hide

Or 

RunWait, %comspec% /c "net start Service_Name",, Hide




Thanks Hardeep
Very useful, is it possible to set the service status to disabled and manual too?

Edit:

I found it out

run, sc config Service_Name start= demand
run, net start Service_Name

* auto--a service automatically started at boot time, even if no user logs on
* boot--a device driver loaded by the boot loader
* demand--a service that must be manually started (the default)
* disabled--a service that can't be started
* system--a service started during kernel initialization



The only thing is that it displays command prompt window, any idea how to do the same without having to see that window?



Deep-Silence
  • Members
  • 89 posts
  • Last active: May 03 2015 05:54 AM
  • Joined: 24 Apr 2009

Thanks guys! Any feedback is highly appreciated.

Will share some more useful functions soon...



Thanks for your nice function.
Would be nice if you could add some code to config the services.

run, sc config Service_Name start= demand


Thanks, Deep-Silence

Aero98
  • Members
  • 112 posts
  • Last active: Mar 29 2013 03:42 PM
  • Joined: 08 Jan 2009
I use this code a lot for stopping and starting our SQL service for some automated backup routines, works 100% no errors, love it. Thanks for sharing.
(\__/) This is Bunny.
(='.'=) Copy and paste Bunny onto your signature.
(")_(") Help Bunny gain World Domination.

hmlnarik
  • Guests
  • Last active:
  • Joined: --
Thanks a lot for the code which I found very useful!

When using 64-bit version of AutoHotKey, it unfortunatelly does not work. There are two issues: 64-bit AHK seems to use wide-strings internally so all ANSI DLL calls should be replaced by their wide equivalents. Further, the original script counts on getting values via NumGet that by default works with 32-bit values. 64-bit version of AHK however works with 64-bit numbers thus it spoils result codes, hence result type must be specified explicitly in NumGet calls.

Here is my fix, feel free to use it if you find it handy.

/* WinServ.ahk
Version			: 1.0-x64
Author			: Hardeep Singh <http://swankyleo.googlepages.com> (modification for 64-bit version by Hynek Mlnarik)
Forum Topic	: http://www.autohotkey.com/forum/viewtopic.php?t=21975
License			: You may use this code freely and without any restriction. If you find it useful, do post your feedback at the
					  above mentioned forum topic.
===============================================================================
Function			: WinServ
Description	: This function can be used to start, stop or query(running status) a windows service on local or a remote
					  computer. Dialogs provide visual feedback when starting/stopping a service or when an error occurs.

~PARAMETERS~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ServiceName	: Specify either the Service Name or the Display Name of the service.

Task				: (Optional) Specify one of the following:
					  True - Starts the service (Returns True if service is started successfully).
					  False - Stops the service (Returns True if service is stopped successfully).
					  NULL(Default) - Query service status (Returns True if service is running).

Silent			: (Optional) Specify one of the following:
					  False(Default) - Show popup dialog for the task being performed or when an error occurs.
					  True - Suppress all popup dialogs including error messages.

Computer		: (Optional) Connect to the service control manager on the specified computer.
					  NULL(Default) - Connect to the service control manager on the local computer.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Return Value	: Returns TRUE or FALSE depending on the task performed.
Notes			: Starting a service which is dependent on other services will also start those services, if not already running.
					  Stopping a service which is dependent on other services will not stop those services.
===============================================================================
*/

WinServ(ServiceName, Task="", Silent=False, Computer="")
{	Global schSCManager, schService
	Static SERVICE_QUERY_STATUS=0x4, SERVICE_START=0x10, SERVICE_STOP=0x20, SC_STATUS_PROCESS_INFO=0, SERVICE_CONTROL_STOP=0x1
	Static SERVICE_STOPPED=0x1, SERVICE_START_PENDING=0x2, SERVICE_STOP_PENDING=0x3, SERVICE_RUNNING=0x4
	VarSetCapacity(@SSP, 36), VarSetCapacity(BytesNeeded, 4), VarSetCapacity(SvcName ,256)

	If Task not in ,0,1
		Return WinServ_ErrMsg("Parameters", ServiceName, Task, False, ErrorLevel:="Invalid Task specified!")
	If !schSCManager := DllCall("Advapi32\OpenSCManagerW", "Str", Computer, "Uint", 0, "Uint", 0)
		Return WinServ_ErrMsg("OpenSCManager", ServiceName, Task, Silent)
	ServiceName := DllCall("Advapi32\GetServiceKeyNameW", "Uint", schSCManager, "Uint", &ServiceName, "Str", SvcName, "UintP", 256) ? SvcName : ServiceName
	If ErrorLevel
		Return WinServ_ErrMsg("GetServiceKeyName", ServiceName, Task, Silent)

	If !schService := DllCall("Advapi32\OpenServiceW", "Uint", schSCManager, "Uint", &ServiceName, "Uint", SERVICE_QUERY_STATUS|SERVICE_START|SERVICE_STOP)
		Return WinServ_ErrMsg("OpenService", ServiceName, Task, Silent)
	ServiceName := DllCall("Advapi32\GetServiceDisplayNameW", "Uint", schSCManager, "Uint", &ServiceName, "Str", SvcName, "UintP", 256) ? SvcName : ServiceName

	Progress, % Task = "" || Silent ? "10:Off" : "10:ZH0 FM10 FS10 B2 H65 W200 ZX2 ZY5", %ServiceName%, % Task ? "Starting service..." : "Stopping service..."
	If (Task = True)
	{	If !DllCall("Advapi32\StartServiceW", "Uint", schService, "Uint", 0, "Uint", 0)
			Return WinServ_ErrMsg("StartService", ServiceName, Task, Silent)
	}	else
	If (Task = False)
	{	If !DllCall("Advapi32\ControlService", "Uint", schService, "Uint", SERVICE_CONTROL_STOP, "Uint", [email protected])
			Return WinServ_ErrMsg("StopService", ServiceName, Task, Silent)
	}
	If !DllCall("Advapi32\QueryServiceStatusEx", "Uint", schService, "Uint", SC_STATUS_PROCESS_INFO, "Uint", [email protected], "Uint", 36, "Uint", &BytesNeeded)
		Return WinServ_ErrMsg("QueryService", ServiceName, Task, Silent)
	If Task =
		Return WinServ_ErrMsg(0,0,0,True)+(NumGet(@SSP, 4, "Uint") = SERVICE_RUNNING)
	StartTickCount := A_TickCount
	OldCheckPoint := NumGet(@SSP, 20, "Uint")
	Loop
	{	If (NumGet(@SSP, 4, "Uint") != (Task ? SERVICE_START_PENDING : SERVICE_STOP_PENDING))
			Break
		WaitTime := NumGet(@SSP, 24, "Uint")/10
		Sleep % WaitTime := WaitTime < 1000 ? 1000 : WaitTime > 10000 ? 10000 : WaitTime
		If !DllCall("Advapi32\QueryServiceStatusEx", "Uint", schService, "Uint", SC_STATUS_PROCESS_INFO, "Uint", [email protected], "Uint", 36, "Uint", &BytesNeeded)
			Return WinServ_ErrMsg("QueryService", ServiceName, Task, Silent)
		If (NumGet(@SSP, 20) > OldCheckPoint)
		{	StartTickCount := A_TickCount
			OldCheckPoint := NumGet(@SSP, 20)
		}	else
		If (A_TickCount-StartTickCount > NumGet(@SSP, 24))
			Break
	}

	If (NumGet(@SSP, 4, "Uint") != (Task ? SERVICE_RUNNING : SERVICE_STOPPED))
		Return WinServ_ErrMsg(Task ? "StartService" : "StopService", ServiceName, Task, Silent, DllCall("SetLastError", "Uint", NumGet(@SSP, 12)))
	Return WinServ_ErrMsg(0,0,0,True)+1
}

;===============================================================================
;Function		: WinServ_ErrMsg
;Description	: This function is used internally by WinServ function.
;===============================================================================
WinServ_ErrMsg(Title, ServiceName, Task="", Silent=False, Dummy="")
{	Global schSCManager, schService
	Progress, 10:Off
	If !Silent
	{	If !ErrorLevel
			VarSetCapacity(LastErrMsg, 1024), DllCall("FormatMessage", "Uint", 0x1000, "Uint", 0, "Uint", LastErrNum:=A_LastError != 123 ? A_LastError : 1060, "Uint", 0, "Str", LastErrMsg, "Uint", 1024, "Uint", 0) ;FORMAT_MESSAGE_FROM_SYSTEM=0x1000
		MsgBox, 262160, WinServ.%Title%: %ServiceName%, % "Could not " (Task = True ? "start {" : Task = False ? "stop {" : "query {") ServiceName "} service.`n`n" (!ErrorLevel ? "Error " LastErrNum ": " LastErrMsg : "Error: " ErrorLevel)
	}	DllCall("Advapi32\CloseServiceHandle", "Uint", schService), DllCall("Advapi32\CloseServiceHandle", "Uint", schSCManager)
	Return False
}


fragman
  • Members
  • 1591 posts
  • Last active: Nov 12 2012 08:51 PM
  • Joined: 13 Oct 2009
Does anyone know how to enumerate the installed services and query description etc. ?

pajenn
  • Members
  • 391 posts
  • Last active: Feb 06 2015 07:57 AM
  • Joined: 07 Feb 2009
thanks for the update. works for me on a 32-bit system as well after the original script stopped working after I switched to the unicode version of AHK.

Thanks a lot for the code which I found very useful!

When using 64-bit version of AutoHotKey, it unfortunatelly does not work. There are two issues: 64-bit AHK seems to use wide-strings internally so all ANSI DLL calls should be replaced by their wide equivalents. Further, the original script counts on getting values via NumGet that by default works with 32-bit values. 64-bit version of AHK however works with 64-bit numbers thus it spoils result codes, hence result type must be specified explicitly in NumGet calls.

Here is my fix, feel free to use it if you find it handy.

/* WinServ.ahk
Version			: 1.0-x64
Author			: Hardeep Singh <http://swankyleo.googlepages.com> (modification for 64-bit version by Hynek Mlnarik)
Forum Topic	: http://www.autohotkey.com/forum/viewtopic.php?t=21975
License			: You may use this code freely and without any restriction. If you find it useful, do post your feedback at the
					  above mentioned forum topic.
===============================================================================
Function			: WinServ
Description	: This function can be used to start, stop or query(running status) a windows service on local or a remote
					  computer. Dialogs provide visual feedback when starting/stopping a service or when an error occurs.

~PARAMETERS~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ServiceName	: Specify either the Service Name or the Display Name of the service.

Task				: (Optional) Specify one of the following:
					  True - Starts the service (Returns True if service is started successfully).
					  False - Stops the service (Returns True if service is stopped successfully).
					  NULL(Default) - Query service status (Returns True if service is running).

Silent			: (Optional) Specify one of the following:
					  False(Default) - Show popup dialog for the task being performed or when an error occurs.
					  True - Suppress all popup dialogs including error messages.

Computer		: (Optional) Connect to the service control manager on the specified computer.
					  NULL(Default) - Connect to the service control manager on the local computer.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Return Value	: Returns TRUE or FALSE depending on the task performed.
Notes			: Starting a service which is dependent on other services will also start those services, if not already running.
					  Stopping a service which is dependent on other services will not stop those services.
===============================================================================
*/

WinServ(ServiceName, Task="", Silent=False, Computer="")
{	Global schSCManager, schService
	Static SERVICE_QUERY_STATUS=0x4, SERVICE_START=0x10, SERVICE_STOP=0x20, SC_STATUS_PROCESS_INFO=0, SERVICE_CONTROL_STOP=0x1
	Static SERVICE_STOPPED=0x1, SERVICE_START_PENDING=0x2, SERVICE_STOP_PENDING=0x3, SERVICE_RUNNING=0x4
	VarSetCapacity(@SSP, 36), VarSetCapacity(BytesNeeded, 4), VarSetCapacity(SvcName ,256)

	If Task not in ,0,1
		Return WinServ_ErrMsg("Parameters", ServiceName, Task, False, ErrorLevel:="Invalid Task specified!")
	If !schSCManager := DllCall("Advapi32\OpenSCManagerW", "Str", Computer, "Uint", 0, "Uint", 0)
		Return WinServ_ErrMsg("OpenSCManager", ServiceName, Task, Silent)
	ServiceName := DllCall("Advapi32\GetServiceKeyNameW", "Uint", schSCManager, "Uint", &ServiceName, "Str", SvcName, "UintP", 256) ? SvcName : ServiceName
	If ErrorLevel
		Return WinServ_ErrMsg("GetServiceKeyName", ServiceName, Task, Silent)

	If !schService := DllCall("Advapi32\OpenServiceW", "Uint", schSCManager, "Uint", &ServiceName, "Uint", SERVICE_QUERY_STATUS|SERVICE_START|SERVICE_STOP)
		Return WinServ_ErrMsg("OpenService", ServiceName, Task, Silent)
	ServiceName := DllCall("Advapi32\GetServiceDisplayNameW", "Uint", schSCManager, "Uint", &ServiceName, "Str", SvcName, "UintP", 256) ? SvcName : ServiceName

	Progress, % Task = "" || Silent ? "10:Off" : "10:ZH0 FM10 FS10 B2 H65 W200 ZX2 ZY5", %ServiceName%, % Task ? "Starting service..." : "Stopping service..."
	If (Task = True)
	{	If !DllCall("Advapi32\StartServiceW", "Uint", schService, "Uint", 0, "Uint", 0)
			Return WinServ_ErrMsg("StartService", ServiceName, Task, Silent)
	}	else
	If (Task = False)
	{	If !DllCall("Advapi32\ControlService", "Uint", schService, "Uint", SERVICE_CONTROL_STOP, "Uint", [email protected])
			Return WinServ_ErrMsg("StopService", ServiceName, Task, Silent)
	}
	If !DllCall("Advapi32\QueryServiceStatusEx", "Uint", schService, "Uint", SC_STATUS_PROCESS_INFO, "Uint", [email protected], "Uint", 36, "Uint", &BytesNeeded)
		Return WinServ_ErrMsg("QueryService", ServiceName, Task, Silent)
	If Task =
		Return WinServ_ErrMsg(0,0,0,True)+(NumGet(@SSP, 4, "Uint") = SERVICE_RUNNING)
	StartTickCount := A_TickCount
	OldCheckPoint := NumGet(@SSP, 20, "Uint")
	Loop
	{	If (NumGet(@SSP, 4, "Uint") != (Task ? SERVICE_START_PENDING : SERVICE_STOP_PENDING))
			Break
		WaitTime := NumGet(@SSP, 24, "Uint")/10
		Sleep % WaitTime := WaitTime < 1000 ? 1000 : WaitTime > 10000 ? 10000 : WaitTime
		If !DllCall("Advapi32\QueryServiceStatusEx", "Uint", schService, "Uint", SC_STATUS_PROCESS_INFO, "Uint", [email protected], "Uint", 36, "Uint", &BytesNeeded)
			Return WinServ_ErrMsg("QueryService", ServiceName, Task, Silent)
		If (NumGet(@SSP, 20) > OldCheckPoint)
		{	StartTickCount := A_TickCount
			OldCheckPoint := NumGet(@SSP, 20)
		}	else
		If (A_TickCount-StartTickCount > NumGet(@SSP, 24))
			Break
	}

	If (NumGet(@SSP, 4, "Uint") != (Task ? SERVICE_RUNNING : SERVICE_STOPPED))
		Return WinServ_ErrMsg(Task ? "StartService" : "StopService", ServiceName, Task, Silent, DllCall("SetLastError", "Uint", NumGet(@SSP, 12)))
	Return WinServ_ErrMsg(0,0,0,True)+1
}

;===============================================================================
;Function		: WinServ_ErrMsg
;Description	: This function is used internally by WinServ function.
;===============================================================================
WinServ_ErrMsg(Title, ServiceName, Task="", Silent=False, Dummy="")
{	Global schSCManager, schService
	Progress, 10:Off
	If !Silent
	{	If !ErrorLevel
			VarSetCapacity(LastErrMsg, 1024), DllCall("FormatMessage", "Uint", 0x1000, "Uint", 0, "Uint", LastErrNum:=A_LastError != 123 ? A_LastError : 1060, "Uint", 0, "Str", LastErrMsg, "Uint", 1024, "Uint", 0) ;FORMAT_MESSAGE_FROM_SYSTEM=0x1000
		MsgBox, 262160, WinServ.%Title%: %ServiceName%, % "Could not " (Task = True ? "start {" : Task = False ? "stop {" : "query {") ServiceName "} service.`n`n" (!ErrorLevel ? "Error " LastErrNum ": " LastErrMsg : "Error: " ErrorLevel)
	}	DllCall("Advapi32\CloseServiceHandle", "Uint", schService), DllCall("Advapi32\CloseServiceHandle", "Uint", schSCManager)
	Return False
}


Hardware: fast laptop with SSD
Software: Win 7 Home Premium 64-bit, android for phone and tablet