AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

[WinServ] Start, Stop or Query a windows service (WinAPI)
Goto page 1, 2  Next
 
Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions
View previous topic :: View next topic  
Author Message
Hardeep



Joined: 02 Jul 2006
Posts: 87

PostPosted: Sat Aug 11, 2007 4:40 pm    Post subject: [WinServ] Start, Stop or Query a windows service (WinAPI) Reply with quote

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.)



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

Code:
;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)
Back to top
View user's profile Send private message
n-l-i-d
Guest





PostPosted: Sat Aug 11, 2007 10:22 pm    Post subject: Reply with quote

Very nice! Cool
Back to top
corrupt



Joined: 29 Dec 2004
Posts: 2485

PostPosted: Sun Aug 12, 2007 2:52 am    Post subject: Reply with quote

Cool Cool . Thanks Smile
Back to top
View user's profile Send private message Visit poster's website
Hardeep



Joined: 02 Jul 2006
Posts: 87

PostPosted: Sun Aug 12, 2007 8:00 pm    Post subject: Reply with quote

Thanks guys! Any feedback is highly appreciated.

Will share some more useful functions soon...
Back to top
View user's profile Send private message
PhiLho



Joined: 27 Dec 2005
Posts: 6836
Location: France (near Paris)

PostPosted: Tue Sep 11, 2007 12:37 pm    Post subject: Reply with quote

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.
_________________
vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2")
Back to top
View user's profile Send private message Visit poster's website
Hardeep



Joined: 02 Jul 2006
Posts: 87

PostPosted: Wed Sep 12, 2007 6:34 pm    Post subject: Reply with quote

PhiLho wrote:
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.
Back to top
View user's profile Send private message
WhoAmIAgain?
Guest





PostPosted: Sat Mar 14, 2009 7:56 pm    Post subject: Reply with quote

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*
Back to top
Gauss



Joined: 10 Sep 2009
Posts: 203

PostPosted: Wed Dec 23, 2009 5:46 pm    Post subject: Reply with quote

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

Edit:

I found it out
Code:
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?
Back to top
View user's profile Send private message
jasonwills
Guest





PostPosted: Thu Feb 04, 2010 11:20 pm    Post subject: Multiple Services Reply with quote

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
Back to top
Deep-Silence



Joined: 24 Apr 2009
Posts: 87

PostPosted: Wed Feb 10, 2010 9:14 pm    Post subject: Reply with quote

Try this code to hide the commandline window

Code:

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

Or

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





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

Edit:

I found it out
Code:
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?
Back to top
View user's profile Send private message
Deep-Silence



Joined: 24 Apr 2009
Posts: 87

PostPosted: Thu Feb 11, 2010 12:57 pm    Post subject: Reply with quote

Hardeep wrote:
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.

Gauss wrote:

Code:

run, sc config Service_Name start= demand



Thanks, Deep-Silence
Back to top
View user's profile Send private message
Aero98



Joined: 08 Jan 2009
Posts: 81
Location: Oklahoma City

PostPosted: Wed Aug 25, 2010 2:33 pm    Post subject: Great code Reply with quote

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.
Back to top
View user's profile Send private message Visit poster's website
hmlnarik
Guest





PostPosted: Sun Oct 17, 2010 11:44 am    Post subject: AutoHotKey 64-bit version Reply with quote

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.

Code:

/* 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", &@SSP)
         Return WinServ_ErrMsg("StopService", ServiceName, Task, Silent)
   }
   If !DllCall("Advapi32\QueryServiceStatusEx", "Uint", schService, "Uint", SC_STATUS_PROCESS_INFO, "Uint", &@SSP, "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", &@SSP, "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
}
Back to top
fragman



Joined: 13 Oct 2009
Posts: 1194

PostPosted: Sun Oct 17, 2010 2:16 pm    Post subject: Reply with quote

Does anyone know how to enumerate the installed services and query description etc. ?
Back to top
View user's profile Send private message
pajenn



Joined: 07 Feb 2009
Posts: 384

PostPosted: Wed Feb 02, 2011 7:00 pm    Post subject: Re: AutoHotKey 64-bit version Reply with quote

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.

hmlnarik wrote:
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.

Code:

/* 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", &@SSP)
         Return WinServ_ErrMsg("StopService", ServiceName, Task, Silent)
   }
   If !DllCall("Advapi32\QueryServiceStatusEx", "Uint", schService, "Uint", SC_STATUS_PROCESS_INFO, "Uint", &@SSP, "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", &@SSP, "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: 1.8 GHz laptop with 4 GB ram, Windows XP/SP3
Software: Prevx, Privatefirewall, KeyScrambler.
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group