 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
heresy
Joined: 11 Mar 2008 Posts: 291
|
Posted: Sat Aug 23, 2008 8:35 am Post subject: Service() - Function set for Handling Windows Services |
|
|
Note : Remote does not supported at the moment though it can be easily modified.
Thanks Lexikos and his StructParser for helping me about structs.
- Service_List(State="", Type="", delimiter="`n") - Get List of Windows Service
State="" Get List of All Windows Service
State="Active" Get List of Active(Running) Windows Service
State="Inactive" Get List of Inactive(Stopped) Windows Service
Type="" Get List of WIN32 Service
Type="Driver" Get List of DRIVER Service
Type="All" Both
- Service_Start(ServiceName)
- Service_Stop(ServiceName)
- Service_State(ServiceName)
- Return Values
SERVICE_STOPPED (1) : The service is not running.
SERVICE_START_PENDING (2) : The service is starting.
SERVICE_STOP_PENDING (3) : The service is stopping.
SERVICE_RUNNING (4) : The service is running.
SERVICE_CONTINUE_PENDING (5) : The service continue is pending.
SERVICE_PAUSE_PENDING (6) : The service pause is pending.
SERVICE_PAUSED (7) : The service is paused.
- Service_Add(ServiceName, BinaryPath, StartType="")
ServiceName ServiceName to be added.
BinaryPath Binary(.exe) path to be added.
StartType="" Start by Demand
StartType="Anything Else" Start automatically
- Service_Delete(ServiceName)
- Generic Return Values
1 : Success
0 : Failure
-4 : Service Not Found
Example
| Code: | MsgBox % Service_List("Active") ;Get List of Running Win32 Service
if Service_State("Print Spooler")=4 ;if Print Spooler service is running
Service_Stop("Print Spooler") ;stop
else if Service_State("Print Spooler")=1 ;if Print Spooler service is not running
Service_Start("Print Spooler") ;start
MsgBox % Service_State("Print Spooler") |
Download Service.ahk
or
Get Source (You need internal function _GetName_() as well)
| Code: | /* Windows Service Control Functions
-heresy
- Return Values
1 : Success
0 : Failure
-4 : Service Not Found
- State codes from Service_State()
SERVICE_STOPPED (1) : The service is not running.
SERVICE_START_PENDING (2) : The service is starting.
SERVICE_STOP_PENDING (3) : The service is stopping.
SERVICE_RUNNING (4) : The service is running.
SERVICE_CONTINUE_PENDING (5) : The service continue is pending.
SERVICE_PAUSE_PENDING (6) : The service pause is pending.
SERVICE_PAUSED (7) : The service is paused.
*/
Service_List(State="", Type="", delimiter="`n"){
if !State
ServiceState := 0x3 ;SERVICE_STATE_ALL (0x00000003)
else if (State="Active")
ServiceState := 0x1 ;SERVICE_ACTIVE (0x00000001)
else if (State="Inactive")
ServiceState := 0x2 ;SERVICE_INACTIVE (0x00000002)
else
ServiceState := 0x3
if !Type
ServiceType := 0x30 ;SERVICE_WIN32 (0x00000030)
else if (Type="Driver")
ServiceType := 0xB ;SERVICE_DRIVER (0x0000000B)
else if (Type="All")
ServiceType := 0x3B ;sum of both
else
ServiceType := 0x30
SCM_HANDLE := DllCall("advapi32\OpenSCManagerA"
, "Int", 0
, "Int", 0
, "UInt", 0x4) ;SC_MANAGER_ENUMERATE_SERVICE (0x0004)
DllCall("advapi32\EnumServicesStatusA"
, "UInt", SCM_HANDLE
, "UInt", ServiceType
, "UInt", ServiceState
, "UInt", 0
, "UInt", 0
, "UIntP", bSize ;get required buffer size first
, "UIntP", 0
, "UIntP", 0)
VarSetCapacity(ENUM_SERVICE_STATUS, bSize, 0) ;prepare struct
DllCall("advapi32\EnumServicesStatusA" ;actual enumeration
, "UInt", SCM_HANDLE
, "UInt", ServiceType
, "UInt", ServiceState
, "UInt", &ENUM_SERVICE_STATUS
, "UInt", bSize
, "UIntP", 0
, "UIntP", ServiceCount
, "UIntP", 0)
Loop, %ServiceCount%
result .= DllCall("MulDiv"
, "Int", NumGet(ENUM_SERVICE_STATUS, (A_Index-1)*36+4)
, "Int", 1
, "Int", 1, "str") . delimiter
DllCall("advapi32\CloseServiceHandle", "UInt", SCM_HANDLE)
Return result
}
Service_Start(ServiceName)
{
ServiceName := _GetName_(ServiceName)
SCM_HANDLE := DllCall("advapi32\OpenSCManagerA"
, "Int", 0 ;NULL for local
, "Int", 0
, "UInt", 0x1) ;SC_MANAGER_CONNECT (0x0001)
if !(SC_HANDLE := DllCall("advapi32\OpenServiceA"
, "UInt", SCM_HANDLE
, "Str", ServiceName
, "UInt", 0x10)) ;SERVICE_START (0x0010)
result := -4 ;Service Not Found
if !result
result := DllCall("advapi32\StartServiceA"
, "UInt", SC_HANDLE
, "Int", 0
, "Int", 0)
DllCall("advapi32\CloseServiceHandle", "UInt", SC_HANDLE)
DllCall("advapi32\CloseServiceHandle", "UInt", SCM_HANDLE)
return result
}
Service_Stop(ServiceName)
{
ServiceName := _GetName_(ServiceName)
SCM_HANDLE := DllCall("advapi32\OpenSCManagerA"
, "Int", 0 ;NULL for local
, "Int", 0
, "UInt", 0x1) ;SC_MANAGER_CONNECT (0x0001)
if !(SC_HANDLE := DllCall("advapi32\OpenServiceA"
, "UInt", SCM_HANDLE
, "Str", ServiceName
, "UInt", 0x20)) ;SERVICE_STOP (0x0020)
result := -4 ;Service Not Found
if !result
result := DllCall("advapi32\ControlService"
, "UInt", SC_HANDLE
, "Int", 1
, "Str", "")
DllCall("advapi32\CloseServiceHandle", "UInt", SC_HANDLE)
DllCall("advapi32\CloseServiceHandle", "UInt", SCM_HANDLE)
return result
}
Service_State(ServiceName)
{ ; Return Values
; SERVICE_STOPPED (1) : The service is not running.
; SERVICE_START_PENDING (2) : The service is starting.
; SERVICE_STOP_PENDING (3) : The service is stopping.
; SERVICE_RUNNING (4) : The service is running.
; SERVICE_CONTINUE_PENDING (5) : The service continue is pending.
; SERVICE_PAUSE_PENDING (6) : The service pause is pending.
; SERVICE_PAUSED (7) : The service is paused.
ServiceName := _GetName_(ServiceName)
SCM_HANDLE := DllCall("advapi32\OpenSCManagerA"
, "Int", 0 ;NULL for local
, "Int", 0
, "UInt", 0x1) ;SC_MANAGER_CONNECT (0x0001)
if !(SC_HANDLE := DllCall("advapi32\OpenServiceA"
, "UInt", SCM_HANDLE
, "Str", ServiceName
, "UInt", 0x4)) ;SERVICE_QUERY_STATUS (0x0004)
result := -4 ;Service Not Found
VarSetCapacity(SC_STATUS, 28, 0) ;SERVICE_STATUS Struct
if !result
result := !DllCall("advapi32\QueryServiceStatus"
, "UInt", SC_HANDLE
, "UInt", &SC_STATUS)
? False : NumGet(SC_STATUS, 4) ;-1 or dwCurrentState
DllCall("advapi32\CloseServiceHandle", "UInt", SC_HANDLE)
DllCall("advapi32\CloseServiceHandle", "UInt", SCM_HANDLE)
return result
}
Service_Add(ServiceName, BinaryPath, StartType=""){
if !A_IsAdmin
Return False
SCM_HANDLE := DllCall("advapi32\OpenSCManagerA"
, "Int", 0
, "Int", 0
, "UInt", 0x2) ;SC_MANAGER_CREATE_SERVICE (0x0002)
StartType := !StartType ? 0x3 : 0x2
;SERVICE_DEMAND_START(0x00000003) vs SERVICE_AUTO_START(0x00000002)
SC_HANDLE := DllCall("advapi32\CreateServiceA"
, "UInt", SCM_HANDLE
, "Str", ServiceName
, "Str", ServiceName
, "UInt", 0xF01FF ;SERVICE_ALL_ACCESS (0xF01FF)
, "UInt", 0x110 ;SERVICE_WIN32_OWN_PROCESS(0x00000010) | SERVICE_INTERACTIVE_PROCESS(0x00000100)
;interactable service with desktop (requires local account)
;http://msdn.microsoft.com/en-us/library/ms683502(VS.85).aspx
, "UInt", StartType
, "UInt", 0x1 ;SERVICE_ERROR_NORMAL(0x00000001)
, "Str", BinaryPath
, "Str", "" ;No Group
, "UInt", 0 ;No TagId
, "Str", "" ;No Dependencies
, "Int", 0 ;Use LocalSystem Account
, "Str", "")
result := A_LastError ? SC_HANDLE "," A_LastError : 1
DllCall("advapi32\CloseServiceHandle", "UInt", SC_HANDLE)
DllCall("advapi32\CloseServiceHandle", "UInt", SCM_HANDLE)
Return result
}
Service_Delete(ServiceName)
{
if !A_IsAdmin ;Requires Administrator rights
Return False
ServiceName := _GetName_(ServiceName)
SCM_HANDLE := DllCall("advapi32\OpenSCManagerA"
, "Int", 0 ;NULL for local
, "Int", 0
, "UInt", 0x1) ;SC_MANAGER_CONNECT (0x0001)
if !(SC_HANDLE := DllCall("advapi32\OpenServiceA"
, "UInt", SCM_HANDLE
, "Str", ServiceName
, "UInt", 0xF01FF)) ;SERVICE_ALL_ACCESS (0xF01FF)
result := -4 ;Service Not Found
if !result
result := DllCall("advapi32\DeleteService", "Uint", SC_HANDLE)
DllCall("advapi32\CloseServiceHandle", "UInt", SC_HANDLE)
Return result
}
_GetName_(DisplayName)
{ ;Internal, Gets Service Name from Display Name,
SCM_HANDLE := DllCall("advapi32\OpenSCManagerA", "Int", 0, "Int", 0, "UInt", 0x1) ;SC_MANAGER_CONNECT (0x0001)
DllCall("advapi32\GetServiceKeyNameA" ;Get Buffer Size
, "Uint", SCM_HANDLE
, "Str", DisplayName
, "Int", 0
, "UintP", Len)
VarSetCapacity(Buffer, Len) ;Prepare Buffer
DllCall("advapi32\GetServiceKeyNameA" ;Get Actual Service Name
, "Uint", SCM_HANDLE
, "Str", DisplayName
, "Uint", &Buffer
, "UintP", Len)
Loop, % Len//2
Output .= Chr(NumGet(Buffer, A_Index-1, "Char"))
return !Output ? DisplayName : Output
} |
_________________ Easy WinAPI - Dive into Windows API World
Benchmark your AutoHotkey skills at PlayAHK.com |
|
| Back to top |
|
 |
BoBo² Guest
|
Posted: Sat Aug 23, 2008 10:44 am Post subject: |
|
|
Kinda coincidence! Desperately searched for something like this a few days ago!!
Thx mate  |
|
| Back to top |
|
 |
Guest
|
|
| Back to top |
|
 |
heresy
Joined: 11 Mar 2008 Posts: 291
|
Posted: Wed Aug 27, 2008 7:19 am Post subject: |
|
|
@ BoBo
glad it helped you!
@ Guest
i've already noticed those functions and that's why i've managed this function set. there was no service_list/add/delete etc(incoming). _________________ Easy WinAPI - Dive into Windows API World
Benchmark your AutoHotkey skills at PlayAHK.com |
|
| Back to top |
|
 |
Chavez
Joined: 20 Aug 2008 Posts: 256
|
Posted: Thu Oct 02, 2008 12:12 pm Post subject: |
|
|
This is EXACTLY what i needed. I'm implementing an application on my work and i needed it to run both logged- and not logged in.
However, i have a small problem with it. I tried making it an automatic service, but it simply adds it as a manual one. And the second problem is when i start it, it will start my application, which is good (note: the application is working entirely, no problems at all), but in the Windows Management Console it keeps saying 'starting...', after a small while it just closes my application again, stating that it didn't reply/crashed.
Is it possibly because i have a loop in my application? _________________ -Chavez. |
|
| Back to top |
|
 |
Chavez
Joined: 20 Aug 2008 Posts: 256
|
Posted: Mon Oct 06, 2008 7:57 am Post subject: |
|
|
Thanks for the help everyone, I'll keep this in mind  _________________ -Chavez. |
|
| Back to top |
|
 |
poo_noo
Joined: 08 Dec 2006 Posts: 248 Location: Sydney Australia
|
|
| Back to top |
|
 |
Chavez
Joined: 20 Aug 2008 Posts: 256
|
Posted: Mon Oct 13, 2008 11:32 am Post subject: |
|
|
Not only is this "REMOVED due to abuse by malware authors", but it will neither help me because i have to install it in the entire company. I have made an in- and uninstaller, the program itself, and that's all i actually needed. The major problem still is that Windows does not see that the service has started successfully and still closes it automatically. _________________ -Chavez. |
|
| Back to top |
|
 |
shajul
Joined: 15 Sep 2006 Posts: 564
|
Posted: Thu Oct 29, 2009 5:54 am Post subject: thanks!! |
|
|
| thanks |
|
| Back to top |
|
 |
shajul
Joined: 15 Sep 2006 Posts: 564
|
Posted: Thu Oct 29, 2009 9:12 am Post subject: Crashes.. |
|
|
Calling service_stop more than once via loop of service names crashes the script..
Any help is appreciated. |
|
| Back to top |
|
 |
pdhawan
Joined: 27 Jul 2006 Posts: 4
|
Posted: Thu Dec 16, 2010 10:30 pm Post subject: Re: Crashes.. |
|
|
thanks for making this.
I am having some difficulty. I can query the service status as to running or not. However, when I do a service start or stop, nothing happens.
Here is a sample of what I am doing.
MsgBox % Service_State("Livescribe Smartpen Service") ; this returns 4
ServiceName := _GetName_("Livescribe Smartpen Service") ; this returns PenCommService
MsgBox % Service_Stop("Livescribe Smartpen Service") ; this returns -4
MsgBox % Service_State("Livescribe Smartpen Service") ; this returns 4
MsgBox % Service_Start("Livescribe Smartpen Service") ; this returns -4
MsgBox % Service_State("Livescribe Smartpen Service") ; this returns 4
Any help is appreciated. I am running on Windows Vista Home Premium. |
|
| Back to top |
|
 |
itaam Guest
|
Posted: Sun Nov 27, 2011 7:44 pm Post subject: |
|
|
| Am I doing something wrong or the script doesn't run in Win7 64? |
|
| Back to top |
|
 |
Ferry
Joined: 18 May 2008 Posts: 23
|
Posted: Mon Nov 28, 2011 9:13 pm Post subject: |
|
|
| Chavez wrote: | This is EXACTLY what i needed. I'm implementing an application on my work and i needed it to run both logged- and not logged in.
However, i have a small problem with it. I tried making it an automatic service, but it simply adds it as a manual one. And the second problem is when i start it, it will start my application, which is good (note: the application is working entirely, no problems at all), but in the Windows Management Console it keeps saying 'starting...', after a small while it just closes my application again, stating that it didn't reply/crashed.
Is it possibly because i have a loop in my application? |
Unfortunatly it is not possible to start any (normal) executable as a windows service. For an executable to start as a service the executable needs to communicate with the Service Control Manager. However, a user named JHa already did this (more or less) as you can see in this topic: http://www.autohotkey.com/forum/topic50967.html&highlight=createservice+schandle
With this knowledge i created the following script as a Service startup script for starting and stopping any normal executable like (for example) Notepad.exe as a Windows Service.
Please be careful using this script and compile this only using AutoHotkey_L Unicode. Credits go to JHa.
| Code: |
/*
Script: AHK Service
Author: Ferry van Gelderen
Date: 12-5-2011
http://msdn.microsoft.com/en-us/library/bb540474%28VS.85%29.aspx
-i Computername* <- Install service
-r Computername* <- Start service
-s Computername* <- Stop service
-d Computername* <- Delete service
*Optional
Compile this script with AutoHotkey_L 32-bit or 64-bit Unicode
*/
#NoEnv
#SingleInstance Ignore
#Persistent
#NoTrayIcon
SendMode Input
SetWorkingDir %A_ScriptDir%
SetBatchLines -1
Version = 1.0
StartProgram = Notepad.exe ; Notepad.exe is used as an example for checking this using windows taskmanager. Enter any normal executable to start as a windows service
SERVICE_AUTO_START = 0x00000002
SERVICE_BOOT_START = 0x00000000
SERVICE_DEMAND_START = 0x00000003
SERVICE_DISABLED = 0x00000004
SERVICE_SYSTEM_START = 0x00000001
SERVICE_ERROR_CRITICAL = 0x00000003
SERVICE_ERROR_IGNORE = 0x00000000
SERVICE_ERROR_NORMAL = 0x00000001
SERVICE_ERROR_SEVERE = 0x00000002
SERVICE_CONTROL_CONTINUE = 0x00000003
SERVICE_CONTROL_INTERROGATE = 0x00000004
SERVICE_CONTROL_NETBINDADD = 0x00000007
SERVICE_CONTROL_NETBINDDISABLE = 0x0000000A
SERVICE_CONTROL_NETBINDENABLE = 0x00000009
SERVICE_CONTROL_NETBINDREMOVE = 0x00000008
SERVICE_CONTROL_PARAMCHANGE = 0x00000006
SERVICE_CONTROL_PAUSE = 0x00000002
SERVICE_CONTROL_STOP = 0x00000001
SERVICE_STOPPED = 0x00000001
SERVICE_START_PENDING = 0x00000002
SERVICE_STOP_PENDING = 0x00000003
SERVICE_RUNNING = 0x00000004
SERVICE_CONTINUE_PENDING = 0x00000005
SERVICE_PAUSE_PENDING = 0x00000006
SERVICE_PAUSED = 0x00000007
SERVICE_ACTIVE = 0x00000001
SERVICE_INACTIVE = 0x00000002
SERVICE_STATE_ALL = 0x00000003
SERVICE_ACCEPT_STOP = 0x00000001
SERVICE_ACCEPT_PAUSE_CONTINUE = 0x00000002
SERVICE_ACCEPT_SHUTDOWN = 0x00000004
SERVICE_ACCEPT_PARAMCHANGE = 0x00000008
SERVICE_ACCEPT_NETBINDCHANGE = 0x00000010
SERVICE_ACCEPT_HARDWAREPROFILECHANGE = 0x00000020
SERVICE_ACCEPT_POWEREVENT = 0x00000040
SERVICE_ACCEPT_SESSIONCHANGE = 0x00000080
SERVICE_ACCEPT_PRESHUTDOWN = 0x00000100
SERVICE_ADAPTER = 0x00000004
SERVICE_FILE_SYSTEM_DRIVER = 0x00000002
SERVICE_KERNEL_DRIVER = 0x00000001
SERVICE_RECOGNIZER_DRIVER = 0x00000008
SERVICE_WIN32_OWN_PROCESS = 0x00000010
SERVICE_WIN32_SHARE_PROCESS = 0x00000020
SERVICE_ALL_ACCESS = 0xF01FF
SERVICE_INTERROGATE = 0x0080
SERVICE_PAUSE_CONTINUE = 0x0040
SERVICE_QUERY_CONFIG = 0x0001
SERVICE_QUERY_STATUS = 0x0004
SERVICE_START = 0x0010
SERVICE_STOP = 0x0020
SERVICE_CONFIG_DESCRIPTION = 1
NO_ERROR = 0x0
SSP =
DesAccess = 0x2
DesiredAccess = 0xF003F
ServiceType := SERVICE_WIN32_OWN_PROCESS ; Change service type
StartType := SERVICE_AUTO_START ; Change service start type
ErrorControl := SERVICE_ERROR_IGNORE
LoadOrderGroup =
TagId =
Dependencies =
ServiceStartName = 0 ; Use 0 for service run as Local System
Password = ; Leave empty for service run as Local System
Description = AutoHotkey Service ; Change the service description
db_Name = AHK_Service ; Change the sevice name
Display_Name = AutoHotkey Service ; Change the service display name
StringTrimRight, s_NameValue, A_ScriptName, 4
p_NameValue = %A_WinDir%\%s_NameValue%.exe run ; Change the service location
If A_IsCompiled <> 1
{
MsgBox, Program is not compiled!
ExitApp
}
LinePar = %1%
m_Name = %2%
; ------------------------------------------------------------< Install Service >------------------------------------------------------------
If LinePar = -i
{
Open_SCManager(m_Name, db_Name, DesAccess)
If Open_Service(sc_Handle, s_NameValue, SERVICE_INTERROGATE)
ExitApp
Else
{
Create_Service(sc_Handle, s_NameValue, Display_Name, DesiredAccess, ServiceType, StartType, ErrorControl, p_NameValue, LoadOrderGroup, TagId, Dependencies, ServiceStartName, Password)
Description_Service(s_Handle, Description)
Close_Service(sc_Handle, s_Handle)
ExitApp
}
}
; ------------------------------------------------------------< Start Service >------------------------------------------------------------
If LinePar = -r
{
Open_SCManager(m_Name, db_Name, DesAccess)
Open_Service(sc_Handle, s_NameValue, SERVICE_START)
Start_Service(s_Handle)
Close_Service(sc_Handle, s_Handle)
ExitApp
}
; ------------------------------------------------------------< Stop Service >------------------------------------------------------------
If LinePar = -s
{
Open_SCManager(m_Name, db_Name, DesAccess)
Open_Service(sc_Handle, s_NameValue, SERVICE_STOP)
Stop_Service(s_Handle)
Close_Service(sc_Handle, s_Handle)
ExitApp
}
; ------------------------------------------------------------< Delete Service >------------------------------------------------------------
If LinePar = -d
{
Open_SCManager(m_Name, db_Name, DesAccess)
Open_Service(sc_Handle, s_NameValue, SERVICE_ALL_ACCESS)
Delete_Service(s_Handle)
Close_Service(sc_Handle, s_Handle)
ExitApp
}
; ------------------------------------------------------------< Run as Service >------------------------------------------------------------
If LinePar = run
{
VarSetCapacity(DispatchTable, 16, 0) ; Use for 32-bit Unicode compiler
; VarSetCapacity(DispatchTable, 32, 0) ; Use for 64-bit Unicode compiler
SvcMainAddress := RegisterCallback("SvcMain")
NumPut(&s_NameValue, DispatchTable, 0)
NumPut(SvcMainAddress, DispatchTable, 4) ; Use for 32-bit Unicode compiler
; NumPut(SvcMainAddress, DispatchTable, 8) ; Use for 64-bit Unicode compiler
cResult := DllCall("Advapi32\StartServiceCtrlDispatcher"
, "UInt", &DispatchTable)
KillResult := DllCall("User32.dll\KillTimer"
, "UInt", 0
, "UInt", UINT_PTR)
ExitApp
}
MsgBox, 64, %Description% %Version%, Usage %Description%:`n`n%s_NameValue%.exe -i Computername* `t <- Install service`n%s_NameValue%.exe -r Computername* `t <- Start service`n%s_NameValue%.exe -s Computername* `t <- Stop service`n%s_NameValue%.exe -d Computername* `t <- Delete service`n`n*Computername is optional.`n`nMake sure the file %A_WinDir%\%s_NameValue%.exe exists in on the (remote) machine running this service.
ExitApp
;-------------------------------------------------------------------------------------------------------------------------------------------------
SvcMain(dwArgc = 0, lpszArgv = 0)
{
Global
Critical
SvcCtrlHandlerAddress := RegisterCallback("SvcCtrlHandler")
SvcStatusHandle := DllCall("Advapi32\RegisterServiceCtrlHandler"
, "Str", s_NameValue
, "UInt", SvcCtrlHandlerAddress)
NumPut(SERVICE_WIN32_OWN_PROCESS, SvcStatus, 0)
NumPut(0, SvcStatus, 16)
ReportSvcStatus(SERVICE_START_PENDING, NO_ERROR, 3000)
hSvcStopEvent := DllCall("CreateEvent"
, "UInt", 0
, "UInt", TRUE
, "UInt", FALSE
, "UInt", 0)
If hSvcStopEvent = 0
{
ReportSvcStatus(SERVICE_STOPPED, NO_ERROR, 0)
Return
}
ReportSvcStatus(SERVICE_RUNNING, NO_ERROR, 0)
ProgAddr := RegisterCallback("UserProg")
UINT_PTR := DllCall("User32.dll\SetTimer"
, "UInt", 0
, "UInt", Timer_1
, "UInt", 1000 ; Change timer in ms
, "UInt", ProgAddr)
Sleep, 1000 ; Sleep is needed to activate timer (UserProg)
cResult := DllCall("WaitForSingleObject"
, "UInt", hSvcStopEvent
, "UInt", -1)
ReportSvcStatus(SERVICE_STOPPED, NO_ERROR, 0)
Return
}
UserProg()
{
Global
Critical
Process, Exist, %StartProgram%
If ErrorLevel = 0
Run, %StartProgram%
Return
}
ReportSvcStatus(CurrentState, Win32ExitCode, WaitHint)
{
Global
Static CheckPoint = 1
NumPut(CurrentState, SvcStatus, 4)
NumPut(Win32ExitCode, SvcStatus, 12)
NumPut(WaitHint, SvcStatus, 24)
If (CurrentState = SERVICE_START_PENDING)
NumPut(0, SvcStatus, 8)
Else
NumPut(SERVICE_ACCEPT_STOP, SvcStatus, 8)
If (CurrentState = SERVICE_RUNNING Or CurrentState = SERVICE_STOPPED)
NumPut(0, SvcStatus, 20)
Else
NumPut(NumGet(SvcStatus, 20)+1, SvcStatus, 20)
cResult := DllCall("Advapi32\SetServiceStatus"
, "UInt", SvcStatusHandle
, "UInt", &SvcStatus)
CurState := NumGet(SvcStatus, 4)
Return
}
SvcCtrlHandler(dwCtrl)
{
Global
Critical
If (dwCtrl = SERVICE_CONTROL_STOP)
{
ReportSvcStatus(SERVICE_STOP_PENDING, NO_ERROR, 0)
CurrentState := NumGet(SvcStatus, 4)
cResult := DllCall("SetEvent"
, "UInt", hSvcStopEvent)
ReportSvcStatus(SERVICE_STOPPED, NO_ERROR, 0)
Return
}
Return
}
SvcReportEvent(ByRef szFunction)
{
Global
hEventSource = DllCall("Advapi32/RegisterEventSource"
, "UInt", 0
, "Str", s_Name)
If hEventSource <> 0
{
DllCall("Advapi32/ReportEvent"
, "UInt", hEventSource
, "UInt", EVENTLOG_ERROR_TYPE
, "UInt", 0
, "UInt", SVC_ERROR
, "UInt", NULL
, "UInt", 2
, "UInt", 0
, "UInt", lpszStrings
, "UInt", NULL)
DllCall("Advapi32/DeregisterEventSource"
, "UInt", hEventSource)
}
Return
}
Open_SCManager(m_Name, db_Name, DesAccess)
{
Global sc_Handle
sc_Handle := DllCall("Advapi32\OpenSCManager"
,"Str", m_Name
,"UInt", db_Name
,"Uint", DesAccess)
Return sc_Handle
}
Create_Service(sc_Handle, s_Name, d_Name, DesiredAccess, ServiceType, StartType, ErrorControl, p_Name, LoadOrderGroup = 0, TagId = 0, Dependencies = "", ServiceStartName = 0, Password = "")
{
Global s_Handle
s_Handle := DllCall("Advapi32\CreateService"
,"UInt", sc_Handle
,"Str", s_Name
,"Str", d_Name
,"UInt", DesiredAccess
,"Uint", ServiceType
,"UInt", StartType
,"UInt", ErrorControl
,"Str", p_Name
,"UInt", LoadOrderGroup
,"UInt", TagId
,"Str", Dependencies
,"UInt", ServiceStartName
,"Str", Password)
Return s_Handle
}
Start_Service(s_Handle)
{
Global
cResult := DllCall("Advapi32\StartService"
, "Uint", s_Handle
, "Uint", 0
, "Str", "")
Return cResult
}
Stop_Service(s_Handle)
{
Global
VarSetCapacity(@SSP, 36)
cResult := DllCall("Advapi32\ControlService"
, "Uint", s_Handle
, "Uint", 0x1
, "Uint", &@SSP)
Return cResult
}
Delete_Service(s_Handle)
{
Global
cResult := DllCall("Advapi32\DeleteService"
, "Uint", s_Handle)
Return cResult
}
Description_Service(s_Handle, Description)
{
Global
cResult := DllCall("Advapi32\ChangeServiceConfig2"
, "UInt", s_Handle
, "UInt", 1
, "Str*", Description)
Return cResult
}
Open_Service(sc_Handle, s_NameValue, DesAccess)
{
Global
s_Handle := DllCall("Advapi32\OpenService"
, "UInt", sc_Handle
, "Str", s_NameValue
, "UInt", DesAccess )
Return s_Handle
}
Close_Service(sc_Handle, s_Handle)
{
DllCall("Advapi32\CloseServiceHandle"
, "Uint", s_Handle)
DllCall("Advapi32\CloseServiceHandle"
, "Uint", sc_Handle)
Return
}
|
It is possible to compile this script as 64-bit Unicode but you need to adjust 2 lines (see remarks in script). If you do not want to use this script you can also use a free program like ServiceEx.
I hope this will help you. |
|
| Back to top |
|
 |
SoggyDog
Joined: 02 May 2006 Posts: 783 Location: Greeley, CO
|
|
| Back to top |
|
 |
twiz
Joined: 08 Nov 2011 Posts: 15
|
Posted: Mon Jan 23, 2012 8:43 pm Post subject: |
|
|
For some reason the Service_Stop() function only stops a function once per script run. After the first run, it would not stop the service, and the returned result would be blank.
I asked about this in the #AHK IRC channel, and BamBam4275 took a look at it and fixed it up. Thanks again, BamBam4275!
Service_Stop() Function fixed by BamBam4275: | Code: | Service_Stop(ServiceName)
{
ServiceName := _GetName_(ServiceName)
SCM_HANDLE := DllCall("advapi32\OpenSCManagerA"
, "Int", 0 ;NULL for local
, "Int", 0
, "UInt", 0x1) ;SC_MANAGER_CONNECT (0x0001)
if !(SC_HANDLE := DllCall("advapi32\OpenServiceA"
, "UInt", SCM_HANDLE
, "Str", ServiceName
, "UInt", 0x20)) ;SERVICE_STOP (0x0020)
result := -4 ;Service Not Found
VarSetCapacity(SC_STATUS, 28, 0)
if !result
result := DllCall("advapi32\ControlService"
, "UInt", SC_HANDLE
, "Int", 1
, "UInt", &SC_STATUS)
DllCall("advapi32\CloseServiceHandle", "UInt", SC_HANDLE)
DllCall("advapi32\CloseServiceHandle", "UInt", SCM_HANDLE)
return result
} |
Whole script: | Code: | /* Windows Service Control Functions
-heresy | Fixed by BamBam4275
http://www.autohotkey.com/forum/topic34984.html
- Return Values
1 : Success
0 : Failure
-4 : Service Not Found
- State codes from Service_State()
SERVICE_STOPPED (1) : The service is not running.
SERVICE_START_PENDING (2) : The service is starting.
SERVICE_STOP_PENDING (3) : The service is stopping.
SERVICE_RUNNING (4) : The service is running.
SERVICE_CONTINUE_PENDING (5) : The service continue is pending.
SERVICE_PAUSE_PENDING (6) : The service pause is pending.
SERVICE_PAUSED (7) : The service is paused.
*/
Service_List(State="", Type="", delimiter="`n"){
if !State
ServiceState := 0x3 ;SERVICE_STATE_ALL (0x00000003)
else if (State="Active")
ServiceState := 0x1 ;SERVICE_ACTIVE (0x00000001)
else if (State="Inactive")
ServiceState := 0x2 ;SERVICE_INACTIVE (0x00000002)
else
ServiceState := 0x3
if !Type
ServiceType := 0x30 ;SERVICE_WIN32 (0x00000030)
else if (Type="Driver")
ServiceType := 0xB ;SERVICE_DRIVER (0x0000000B)
else if (Type="All")
ServiceType := 0x3B ;sum of both
else
ServiceType := 0x30
SCM_HANDLE := DllCall("advapi32\OpenSCManagerA"
, "Int", 0
, "Int", 0
, "UInt", 0x4) ;SC_MANAGER_ENUMERATE_SERVICE (0x0004)
DllCall("advapi32\EnumServicesStatusA"
, "UInt", SCM_HANDLE
, "UInt", ServiceType
, "UInt", ServiceState
, "UInt", 0
, "UInt", 0
, "UIntP", bSize ;get required buffer size first
, "UIntP", 0
, "UIntP", 0)
VarSetCapacity(ENUM_SERVICE_STATUS, bSize, 0) ;prepare struct
DllCall("advapi32\EnumServicesStatusA" ;actual enumeration
, "UInt", SCM_HANDLE
, "UInt", ServiceType
, "UInt", ServiceState
, "UInt", &ENUM_SERVICE_STATUS
, "UInt", bSize
, "UIntP", 0
, "UIntP", ServiceCount
, "UIntP", 0)
Loop, %ServiceCount%
result .= DllCall("MulDiv"
, "Int", NumGet(ENUM_SERVICE_STATUS, (A_Index-1)*36+4)
, "Int", 1
, "Int", 1, "str") . delimiter
DllCall("advapi32\CloseServiceHandle", "UInt", SCM_HANDLE)
Return result
}
Service_Start(ServiceName)
{
ServiceName := _GetName_(ServiceName)
SCM_HANDLE := DllCall("advapi32\OpenSCManagerA"
, "Int", 0 ;NULL for local
, "Int", 0
, "UInt", 0x1) ;SC_MANAGER_CONNECT (0x0001)
if !(SC_HANDLE := DllCall("advapi32\OpenServiceA"
, "UInt", SCM_HANDLE
, "Str", ServiceName
, "UInt", 0x10)) ;SERVICE_START (0x0010)
result := -4 ;Service Not Found
if !result
result := DllCall("advapi32\StartServiceA"
, "UInt", SC_HANDLE
, "Int", 0
, "Int", 0)
DllCall("advapi32\CloseServiceHandle", "UInt", SC_HANDLE)
DllCall("advapi32\CloseServiceHandle", "UInt", SCM_HANDLE)
return result
}
Service_Stop(ServiceName)
{
ServiceName := _GetName_(ServiceName)
SCM_HANDLE := DllCall("advapi32\OpenSCManagerA"
, "Int", 0 ;NULL for local
, "Int", 0
, "UInt", 0x1) ;SC_MANAGER_CONNECT (0x0001)
if !(SC_HANDLE := DllCall("advapi32\OpenServiceA"
, "UInt", SCM_HANDLE
, "Str", ServiceName
, "UInt", 0x20)) ;SERVICE_STOP (0x0020)
result := -4 ;Service Not Found
VarSetCapacity(SC_STATUS, 28, 0)
if !result
result := DllCall("advapi32\ControlService"
, "UInt", SC_HANDLE
, "Int", 1
, "UInt", &SC_STATUS)
DllCall("advapi32\CloseServiceHandle", "UInt", SC_HANDLE)
DllCall("advapi32\CloseServiceHandle", "UInt", SCM_HANDLE)
return result
}
Service_State(ServiceName)
{ ; Return Values
; SERVICE_STOPPED (1) : The service is not running.
; SERVICE_START_PENDING (2) : The service is starting.
; SERVICE_STOP_PENDING (3) : The service is stopping.
; SERVICE_RUNNING (4) : The service is running.
; SERVICE_CONTINUE_PENDING (5) : The service continue is pending.
; SERVICE_PAUSE_PENDING (6) : The service pause is pending.
; SERVICE_PAUSED (7) : The service is paused.
ServiceName := _GetName_(ServiceName)
SCM_HANDLE := DllCall("advapi32\OpenSCManagerA"
, "Int", 0 ;NULL for local
, "Int", 0
, "UInt", 0x1) ;SC_MANAGER_CONNECT (0x0001)
if !(SC_HANDLE := DllCall("advapi32\OpenServiceA"
, "UInt", SCM_HANDLE
, "Str", ServiceName
, "UInt", 0x4)) ;SERVICE_QUERY_STATUS (0x0004)
result := -4 ;Service Not Found
VarSetCapacity(SC_STATUS, 28, 0) ;SERVICE_STATUS Struct
if !result
result := !DllCall("advapi32\QueryServiceStatus"
, "UInt", SC_HANDLE
, "UInt", &SC_STATUS)
? False : NumGet(SC_STATUS, 4) ;-1 or dwCurrentState
DllCall("advapi32\CloseServiceHandle", "UInt", SC_HANDLE)
DllCall("advapi32\CloseServiceHandle", "UInt", SCM_HANDLE)
return result
}
Service_Add(ServiceName, BinaryPath, StartType=""){
if !A_IsAdmin
Return False
SCM_HANDLE := DllCall("advapi32\OpenSCManagerA"
, "Int", 0
, "Int", 0
, "UInt", 0x2) ;SC_MANAGER_CREATE_SERVICE (0x0002)
StartType := !StartType ? 0x3 : 0x2
;SERVICE_DEMAND_START(0x00000003) vs SERVICE_AUTO_START(0x00000002)
SC_HANDLE := DllCall("advapi32\CreateServiceA"
, "UInt", SCM_HANDLE
, "Str", ServiceName
, "Str", ServiceName
, "UInt", 0xF01FF ;SERVICE_ALL_ACCESS (0xF01FF)
, "UInt", 0x110 ;SERVICE_WIN32_OWN_PROCESS(0x00000010) | SERVICE_INTERACTIVE_PROCESS(0x00000100)
;interactable service with desktop (requires local account)
;http://msdn.microsoft.com/en-us/library/ms683502(VS.85).aspx
, "UInt", StartType
, "UInt", 0x1 ;SERVICE_ERROR_NORMAL(0x00000001)
, "Str", BinaryPath
, "Str", "" ;No Group
, "UInt", 0 ;No TagId
, "Str", "" ;No Dependencies
, "Int", 0 ;Use LocalSystem Account
, "Str", "")
result := A_LastError ? SC_HANDLE "," A_LastError : 1
DllCall("advapi32\CloseServiceHandle", "UInt", SC_HANDLE)
DllCall("advapi32\CloseServiceHandle", "UInt", SCM_HANDLE)
Return result
}
Service_Delete(ServiceName)
{
if !A_IsAdmin ;Requires Administrator rights
Return False
ServiceName := _GetName_(ServiceName)
SCM_HANDLE := DllCall("advapi32\OpenSCManagerA"
, "Int", 0 ;NULL for local
, "Int", 0
, "UInt", 0x1) ;SC_MANAGER_CONNECT (0x0001)
if !(SC_HANDLE := DllCall("advapi32\OpenServiceA"
, "UInt", SCM_HANDLE
, "Str", ServiceName
, "UInt", 0xF01FF)) ;SERVICE_ALL_ACCESS (0xF01FF)
result := -4 ;Service Not Found
if !result
result := DllCall("advapi32\DeleteService", "Uint", SC_HANDLE)
DllCall("advapi32\CloseServiceHandle", "UInt", SC_HANDLE)
Return result
}
_GetName_(DisplayName)
{ ;Internal, Gets Service Name from Display Name,
SCM_HANDLE := DllCall("advapi32\OpenSCManagerA", "Int", 0, "Int", 0, "UInt", 0x1) ;SC_MANAGER_CONNECT (0x0001)
DllCall("advapi32\GetServiceKeyNameA" ;Get Buffer Size
, "Uint", SCM_HANDLE
, "Str", DisplayName
, "Int", 0
, "UintP", Len)
VarSetCapacity(Buffer, Len) ;Prepare Buffer
DllCall("advapi32\GetServiceKeyNameA" ;Get Actual Service Name
, "Uint", SCM_HANDLE
, "Str", DisplayName
, "Uint", &Buffer
, "UintP", Len)
Loop, % Len//2
Output .= Chr(NumGet(Buffer, A_Index-1, "Char"))
return !Output ? DisplayName : Output
}
|
|
|
| Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|