AutoHotkey Community

It is currently May 26th, 2012, 10:57 am

All times are UTC [ DST ]




Post new topic Reply to topic  [ 16 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: August 23rd, 2008, 9:35 am 
Offline

Joined: March 11th, 2008, 11:36 pm
Posts: 291
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


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: August 23rd, 2008, 11:44 am 
Kinda coincidence! Desperately searched for something like this a few days ago!!
Thx mate :D


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: August 23rd, 2008, 4:07 pm 
http://www.autohotkey.com/forum/topic16758.html
http://www.autohotkey.com/forum/topic21975.html


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: August 27th, 2008, 8:19 am 
Offline

Joined: March 11th, 2008, 11:36 pm
Posts: 291
@ 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


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 2nd, 2008, 1:12 pm 
Offline

Joined: August 20th, 2008, 4:25 pm
Posts: 256
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.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 6th, 2008, 8:57 am 
Offline

Joined: August 20th, 2008, 4:25 pm
Posts: 256
Thanks for the help everyone, I'll keep this in mind :x

_________________
-Chavez.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 11th, 2008, 6:55 am 
Offline

Joined: December 8th, 2006, 5:17 am
Posts: 248
Location: Sydney Australia
Chavez
maybe this ? http://www.bitsum.com/other.php#makeservice

_________________
Paul O


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 13th, 2008, 12:32 pm 
Offline

Joined: August 20th, 2008, 4:25 pm
Posts: 256
poo_noo wrote:


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.


Report this post
Top
 Profile  
Reply with quote  
 Post subject: thanks!!
PostPosted: October 29th, 2009, 6:54 am 
Offline

Joined: September 15th, 2006, 10:25 am
Posts: 567
thanks


Report this post
Top
 Profile  
Reply with quote  
 Post subject: Crashes..
PostPosted: October 29th, 2009, 10:12 am 
Offline

Joined: September 15th, 2006, 10:25 am
Posts: 567
Calling service_stop more than once via loop of service names crashes the script..
Any help is appreciated.


Report this post
Top
 Profile  
Reply with quote  
 Post subject: Re: Crashes..
PostPosted: December 16th, 2010, 11:30 pm 
Offline

Joined: July 28th, 2006, 12:55 am
Posts: 4
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.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: November 27th, 2011, 8:44 pm 
Am I doing something wrong or the script doesn't run in Win7 64?


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: November 28th, 2011, 10:13 pm 
Offline

Joined: May 18th, 2008, 9:39 pm
Posts: 27
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.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: November 28th, 2011, 10:58 pm 
Offline

Joined: May 2nd, 2006, 11:16 pm
Posts: 800
Location: Greeley, CO
Ferry wrote:
If you do not want to use this script you can also use a free program like ServiceEx.

Agreed;
ServiceEx works like a charm.

_________________
Image
SoggyDog
Dwarf Fortress:
"The most intriguing game I've ever played."


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: January 23rd, 2012, 9:43 pm 
Offline

Joined: November 8th, 2011, 6:16 pm
Posts: 17
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
}


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 16 posts ]  Go to page 1, 2  Next

All times are UTC [ DST ]


Who is online

Users browsing this forum: Exabot [Bot], sks and 11 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group