-
Notifications
You must be signed in to change notification settings - Fork 72
/
Copy pathWinServW.ahk
106 lines (96 loc) · 6.52 KB
/
WinServW.ahk
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
; Link: https://github.com/jixiuf/my_autohotkey_scripts/blob/master/ahk_scripts/anything-services.ahk
; Author:
; Date:
; for: AHK_L
/*
*/
/* WinServ.ahk
; http://www.autohotkey.com/forum/topic21975.html
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\GetServiceDisplay_NameW", "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
}