Jump to content
Sign in to follow this  
arcker

_Service_UDF v4 : Build your own service with autoit code

Recommended Posts

@arcker : thank you for that UDF, it helped me to add driver (service) into a WinPE only when I need it (without any modification into boot.wim).

Very useful :sorcerer:

Share this post


Link to post
Share on other sites

I want to make a GUI. I have read almost all comments. If making gui is impossible, why there is an option "allow service to interact with desktop" on services? How do run Teamviewer, Radmin, Windows Camera Login programs? I can say many more program. They can record even login screen and they have gui. I am sure that making GUI and access desktop with services.

kodevreni_1423223270__keylemon-windows-7

At least can we run a program with an other user? Teamviewer Service can run Teamviewer interface with my user account on desktop.

Please do not say Windows startup. It seems that Teamviewer Service has started the Teamviewer Interface on Process Explorer.

kodevreni_1423224348__screenshot_2.png

Edited by Adele

Share this post


Link to post
Share on other sites

I try build a service with interactive GUI too. It not work very well, it's run on Session 0. Not good.

I knew many IPC (Interprocess comunication), but I discover many limitations too (_Pipes is very cool, realy like it).

But, the best way was create a TCP/IP comunicaton betwen applications (for me).

Have more work... But is cool.

There are many and great examples in the forum, I have time to test >this example of communication.

I build a windows service, running in a administrative account. It answer for any client (any account). Work very very well.
I use JSON to code/chain the data. Very well too.

Edited by Detefon

Visit my repository

Share this post


Link to post
Share on other sites

Well, can we start GUI program from the service on the user account? Maybe RunAs function but it requires password.

For example, Teamviewer Service starts own gui program with current user without using Windows starting. (Image is from Process Explorer)

kodevreni_1423230142__screenshot_3.png

Edited by Adele

Share this post


Link to post
Share on other sites

No at user account, properly, in Session 0 o Isolated Session.
The result is not like a normal app launch.

RunAs, you are write, need password. I launch App in user acount by Windows Task Manager. Not need password required.


Visit my repository

Share this post


Link to post
Share on other sites

No at user account, properly, in Session 0 o Isolated Session.

The result is not like a normal app launch.

RunAs, you are write, need password. I launch App in user acount by Windows Task Manager. Not need password required.

 

kodevreni_1423235450__screenshot_4.png

It seems here that Teamviewer Service can start Teamviewer interface with Session 1 at user account.

Edited by Adele

Share this post


Link to post
Share on other sites

You can of course create IPCs to communicate between service and process.

Programs like antivirus, teamviewer or other that starts both use an api to retrieve the current logged on users, and start a "gui" in it.

I've manage to do it, but can't refind the script

the api is somethink run as process token, search for it.


-- Arck System _ Soon -- Ideas make everything

"La critique est facile, l'art est difficile"

Projects :

[list] [*]Au3Service : Run your exe as service V3 / Updated 29/07/2013 Get it Here [/list]

Share this post


Link to post
Share on other sites

Just an FYI:
I added the ability to add the description in the "_Service_Create" function.  I just added a new optional param "$sDescription = Default" and plopped this bit of code in the function.

;## Set Description
        If $sDescription <> Default Then
            Local $serviceDescription = DllStructCreate("ptr")
            Local $caDescription = DllStructCreate("char[260]")
            DllStructSetData($caDescription, 1, $sDescription)
            DllStructSetData($serviceDescription, 1, DllStructGetPtr($caDescription))
            DllCall($hAdvapi32_DLL, "int", "ChangeServiceConfig2", "long", $avSC[0], "long", 1, "long", DllStructGetPtr($serviceDescription))
        EndIf
        CloseServiceHandle($avSC[0]) ;<-- Line that already exists in function

Works great for me.  ^u^


--- TTFN

Share this post


Link to post
Share on other sites

Oh! I want this knowledge!

I will go study more (much more).

 

You can run a proccess in the interactive account, session 1, the logon account, by impersonating it from any account.

I am interested in know what limitations did you find with Pipes, and go for TCP/IP ?. I ask because is more complex and slower in same machine, and i am working with pipes now. Thanks.

Edited by zalomalo

My english shucks, i know it.

Share this post


Link to post
Share on other sites

Is anyone else suddenly finding their service wont run anymore producing an "error 13" (data is invalid) on windows 7 or is it just me? ... unless I accidently changed something and its not producing an syntax error my code hasnt changed and it used to work fine a few months ago...  its fine following the initial installation but after reboot wont start again unless i uninstall and re-install...

Edited by Lecdev

Share this post


Link to post
Share on other sites

Is anyone else suddenly finding their service wont run anymore producing an "error 13" (data is invalid) on windows 7 or is it just me? ... unless I accidently changed something and its not producing an syntax error my code hasnt changed and it used to work fine a few months ago...  its fine following the initial installation but after reboot wont start again unless i uninstall and re-install...

to be honest my old services scripts are running in previous clients i had, and i've not be warned of it. I've not made services or scripted services since a while now. I've plan to update it but not today.

Do you have a security patch applied since the problems ? No reason for the services to run better after a uninstall / reinstall. The exe remains the same.

I'll take a look if you can provide me more informations  :)


-- Arck System _ Soon -- Ideas make everything

"La critique est facile, l'art est difficile"

Projects :

[list] [*]Au3Service : Run your exe as service V3 / Updated 29/07/2013 Get it Here [/list]

Share this post


Link to post
Share on other sites

bug report:

working with the source package (v4), AutoIt version 3.3.12.0 with Beta version 3.3.13.19 on Windows 7 Ultimate 64-bit and Windows 8 Pro 64-bit.

i compiled the file ServiceExample_v4.au3 into exe, took the x64 version, launched it with -i. i went into services.msc, opened the properties of the service, started it - it was started successfully. so far so good.

then i switched to the "Dependencies" tab, and the service was suddenly stopped!

the Event Log shows no error, only the standard event about the service entering the "Stopped" state.

same effect with the 32-bit compiled exe, and same effect for both exe's on both OS's mentioned above.

 

 

as far as i can see, the stop is triggered when i switch into the "Dependencies" tab. to see it i launch:

sc query "AutoIt_Service"

and i see:

STATE: 4  RUNNING

then go to the "Dependencies" tab, and without doing anything else, call again the sc query, then see:

STATE: 1  STOPPED

Share this post


Link to post
Share on other sites

following previous post: i found an older version of the UDF lying around on my pc, one with the service named "SessionChange". that version does not exhibit the bug mentioned in previous post.

inconveniently, the UDF does not have version numbering in its header. so here it is:

#include-once

#include "Log.au3"
#include "WinAPI.au3"
#include "ServicesConstants.au3"

; #INDEX# ==========================================================================================================================================================
; Title .........: Services
; AutoIt Version : 3.2.10++
; Language ......: English
; Description ...: Windows service management for AutoIt, with AutoIt-as-service functionality.
; Authors .......: Engine, Arcker
; ...............: Shminkyboy, udgeen
; ==================================================================================================================================================================



; #FUNCTION# =======================================================================================================================================================
; Name...........: _Service_Create
; Description ...: Creates a service.
; Syntax.........: _Service_Create($sServiceName, $sDisplayName, $iServiceType, $iStartType, $iErrorControl, $sBinaryPath _
;                  [, $sLoadOrderGroup, $fTagId, $vDependencies, $sServiceUser, $sPassword, $sComputerName])
; Parameters ....: $sServiceName - Name of the service.
;                  $sDisplayName - The display name to be used by user interface programs to identify the service. The maximum string length is 256 characters.
;                                  The service control manager database preserves the case of the characters,
;                                  but service name comparisons are always case insensitive.
;                                  Forward-slash (/) and back-slash (\) are invalid service name characters.
;                  $iServiceType - The type of service. Specify one of the following service types:
;                                  $SERVICE_KERNEL_DRIVER - Driver service.
;                                  $SERVICE_FILE_SYSTEM_DRIVER - File system driver service.
;                                  $SERVICE_WIN32_OWN_PROCESS - Service that runs in its own process.
;                                  $SERVICE_WIN32_SHARE_PROCESS - Service that shares a process with other services.
;                                  If you specify either $SERVICE_WIN32_OWN_PROCESS or $SERVICE_WIN32_SHARE_PROCESS,
;                                  and the service is running in the context of the LocalSystem account, you can also specify the following type:
;                                  $SERVICE_INTERACTIVE_PROCESS - The service can interact with the desktop.
;                  $iStartType - The service start options. Specify one of the following start types:
;                                $SERVICE_BOOT_START - A device driver started by the system loader. This value is valid only for driver services.
;                                $SERVICE_SYSTEM_START - A device driver started by the IoInitSystem function. This value is valid only for driver services.
;                                $SERVICE_AUTO_START - A service started automatically by the service control manager during system startup.
;                                $SERVICE_DEMAND_START - A service started by the service control manager when a process calls the StartService function.
;                                $SERVICE_DISABLED - A service that cannot be started.
;                  $iErrorControl - The severity of the error, and action taken, if this service fails to start. Specify one of the following values:
;                                   $SERVICE_ERROR_IGNORE - The startup program ignores the error and continues the startup operation.
;                                   $SERVICE_ERROR_NORMAL - The startup program logs the error in the event log but continues the startup operation.
;                                   $SERVICE_ERROR_SEVERE - The startup program logs the error in the event log.
;                                                           If the last-known-good configuration is being started, the startup operation continues.
;                                                           Otherwise, the system is restarted with the last-known-good configuration.
;                                   $SERVICE_ERROR_CRITICAL - The startup program logs the error in the event log, if possible.
;                                                             If the last-known-good configuration is being started, the startup operation fails.
;                                                             Otherwise, the system is restarted with the last-known good configuration.
;                  $sBinaryPath - The fully-qualified path to the service binary file. If the path contains a space,
;                                 it must be quoted so that it is correctly interpreted.
;                                 For example, "d:\\my share\\myservice.exe" should be specified as "\"d:\\my share\\myservice.exe\"".
;                                 The path can also include arguments for an auto-start service. For example, "d:\\myshare\\myservice.exe arg1 arg2".
;                                 These arguments are passed to the service entry point (typically the main function).
;                  $sLoadOrderGroup - [Optional] The name of the load ordering group of which this service is a member.
;                                     Specify "Default" or an empty string if the service does not belong to a group.
;                  $fTagId - [Optional] Specify "True" if you desire a tag value that is unique in the group specified in the $sLoadOrderGroup parameter.
;                            Specify "False" or "Default" if you do not desire a tag value.
;                            The tag value is stored in @extended macro.
;                            You can use a tag for ordering service startup within a load ordering group by specifying a tag order vector in the
;                            GroupOrderList value of the following registry key:
;                            HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control
;                            Tags are only evaluated for driver services that have $SERVICE_BOOT_START or $SERVICE_SYSTEM_START start types.
;                  $vDependencies - [Optional] An array of services or load ordering groups that the system must start before this service can be started.
;                                   (Dependency on a group means that this service can run if at least one member of the group is running after an attempt to
;                                   start all members of the group.) Specify "Default" or an empty string if the service has no dependencies.
;                                   You must prefix group names with a plus sign ("+") so that they can be distinguished from a service name,
;                                   because services and service groups share the same name space.
;                  $sServiceUser - [Optional] The name of the account under which the service should run.
;                                  If the service type is $SERVICE_WIN32_OWN_PROCESS, use an account name in the form DomainName\UserName.
;                                  The service process will be logged on as this user. If the account belongs to the built-in domain,
;                                  you can specify .\UserName . A shared process can run as any user.
;                                  If the service type is $SERVICE_KERNEL_DRIVER or $SERVICE_FILE_SYSTEM_DRIVER,
;                                  the name is the driver object name that the system uses to load the device driver.
;                                  Specify "Default" if the driver is to use a default object name created by the I/O system.
;                  $sPassword - [Optional] The password to the account name specified by the $sServiceUser parameter.
;                               Specify "Default" or an empty string if the account has no password or if the service runs in the LocalService, NetworkService,
;                               or LocalSystem account. Passwords are ignored for driver services.
;                  $sComputerName - [Optional] The name of the target computer. The local computer is default.
; Requirement(s).: Administrative rights on the target computer.
; Return values .: Success - 1
;                  Failure - 0
;                            Sets @error
; Author ........: engine
; Modified.......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......:
; ==================================================================================================================================================================

Func _Service_Create($sServiceName, _
        $sDisplayName, _
        $iServiceType, _
        $iStartType, _
        $iErrorControl, _
        $sBinaryPath, _
        $sLoadOrderGroup = Default, _
        $fTagId = Default, _
        $vDependencies = Default, _
        $sServiceUser = Default, _
        $sPassword = Default, _
        $sComputerName = "")
    Local $tLoadOrderGroup, $tTagId, $tDepend, $tServiceUser, $tPassword, $hSC, $avSC, $iSC
    $tLoadOrderGroup = DllStructCreate("wchar[" & Number($sLoadOrderGroup <> Default) * (StringLen($sLoadOrderGroup) + 1) & "]")
    DllStructSetData($tLoadOrderGroup, 1, $sLoadOrderGroup)
    $tTagId = DllStructCreate("dword[" & Number($fTagId) & "]")
    If IsArray($vDependencies) Then
        Local $iDepend, $tagDepend
        $iDepend = UBound($vDependencies) - 1
        For $i = 0 To $iDepend
            $tagDepend &= "wchar[" & StringLen($vDependencies[$i]) + 1 & "];"
        Next
        $tDepend = DllStructCreate(StringTrimRight($tagDepend, 1))
        For $i = 0 To $iDepend
            DllStructSetData($tDepend, $i + 1, $vDependencies[$i])
        Next
    Else
        $tDepend = DllStructCreate("wchar[" & Number($vDependencies <> Default) * (StringLen($vDependencies) + 1) & "]")
        DllStructSetData($tDepend, 1, $vDependencies)
    EndIf
    $tServiceUser = DllStructCreate("wchar[" & Number($sServiceUser <> Default) * (StringLen($sServiceUser) + 1) & "]")
    DllStructSetData($tServiceUser, 1, $sServiceUser)
    $tPassword = DllStructCreate("wchar[" & Number($sPassword <> Default) * (StringLen($sPassword) + 1) & "]")
    DllStructSetData($tPassword, 1, $sPassword)
    $hSC = OpenSCManager($sComputerName, $SC_MANAGER_CREATE_SERVICE)
    $avSC = DllCall($ghADVAPI32, "ptr", "CreateServiceW", _
            "ptr", $hSC, _
            "wstr", $sServiceName, _
            "wstr", $sDisplayName, _
            "dword", $SERVICE_ALL_ACCESS, _
            "dword", $iServiceType, _
            "dword", $iStartType, _
            "dword", $iErrorControl, _
            "wstr", $sBinaryPath, _
            "ptr", DllStructGetPtr($tLoadOrderGroup), _
            "ptr", DllStructGetPtr($tTagId), _
            "ptr", DllStructGetPtr($tDepend), _
            "ptr", DllStructGetPtr($tServiceUser), _
            "ptr", DllStructGetPtr($tPassword))
    If $avSC[0] = 0 Then
        $iSC = _WinAPI_GetLastError()
    Else
        CloseServiceHandle($avSC[0])
    EndIf
    CloseServiceHandle($hSC)
    Return SetError($iSC, DllStructGetData($tTagId, 1), Number($avSC[0] <> 0))
EndFunc   ;==>_Service_Create



; #FUNCTION# =======================================================================================================================================================
; Name...........: _Service_Delete
; Description ...: Deletes a service.
; Syntax.........: _Service_Delete($sServiceName [, $sComputerName])
; Parameters ....: $sServiceName - Name of the service.
;                  $sComputerName - [Optional] The name of the target computer. The local computer is default.
; Requirement(s).: Administrative rights on the target computer.
; Return values .: Success - 1
;                  Failure - 0
;                            Sets @error
; Author ........: engine
; Modified.......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......:
; ==================================================================================================================================================================

Func _Service_Delete($sServiceName, $sComputerName = "")
    Local $hSC, $hService, $avDS, $iDS
    $hSC = OpenSCManager($sComputerName, $SC_MANAGER_CONNECT)
    $hService = OpenService($hSC, $sServiceName, $DELETE)
    $avDS = DllCall($ghADVAPI32, "int", "DeleteService", _
            "ptr", $hService)
    If $avDS[0] = 0 Then $iDS = _WinAPI_GetLastError()
    CloseServiceHandle($hService)
    CloseServiceHandle($hSC)
    Return SetError($iDS, 0, $avDS[0])
EndFunc   ;==>_Service_Delete



; #FUNCTION# =======================================================================================================================================================
; Name...........: _Service_Exists
; Description ...: Checks if a service exists.
; Syntax.........: _Service_Exists($sServiceName [, $sComputerName])
; Parameters ....: $sServiceName - Name of the service.
;                  $sComputerName - [Optional] The name of the target computer. The local computer is default.
; Requirement(s).: None.
; Return values .: Success - 1
;                  Failure - 0
; Author ........: engine
; Modified.......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......:
; ==================================================================================================================================================================

Func _Service_Exists($sServiceName, $sComputerName = "")
    Local $hSC, $hService
    $hSC = OpenSCManager($sComputerName, $SC_MANAGER_CONNECT)
    $hService = OpenService($hSC, $sServiceName, $SERVICE_INTERROGATE)
    CloseServiceHandle($hService)
    CloseServiceHandle($hSC)
    Return Number($hService <> 0)
EndFunc   ;==>_Service_Exists



; #FUNCTION# =======================================================================================================================================================
; Name...........: _Service_QueryType
; Description ...: Retrieves a service's type.
; Syntax.........: _Service_QueryType($sServiceName [, $sComputerName])
; Parameters ....: $sServiceName - Name of the service.
;                  $sComputerName - [Optional] The name of the target computer. The local computer is default.
; Requirement(s).: None.
; Return values .: Success - Returns the type of service. Can be one of the following values:
;                            $SERVICE_KERNEL_DRIVER - The service is a device driver.
;                            $SERVICE_FILE_SYSTEM_DRIVER - The service is a file system driver.
;                            $SERVICE_WIN32_OWN_PROCESS - The service runs in its own process.
;                            $SERVICE_WIN32_SHARE_PROCESS - The service shares a process with other services.
;                            BitOR($SERVICE_WIN32_OWN_PROCESS, $SERVICE_INTERACTIVE_PROCESS) - The service runs in its own process
;                                                                                              and can interact with the desktop.
;                            BitOR($SERVICE_WIN32_SHARE_PROCESS, $SERVICE_INTERACTIVE_PROCESS) - The service shares a process with other services
;                                                                                                and can interact with the desktop.
;                  Failure - 0
;                            Sets @error
; Author ........: engine
; Modified.......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......:
; ==================================================================================================================================================================

Func _Service_QueryType($sServiceName, $sComputerName = "")
    Local $hSC, $hService, $avQA, $tQB, $avQB, $iQE, $tQC
    $hSC = OpenSCManager($sComputerName, $SC_MANAGER_CONNECT)
    $hService = OpenService($hSC, $sServiceName, $SERVICE_QUERY_CONFIG)

    ; Determine needed size of the struct in bytes
    $avQA = QueryServiceConfig($hService, 0, 0)

    ; Get Service data
    $tQB = DllStructCreate("ubyte[" & $avQA[4] & "]")
    $avQB = QueryServiceConfig($hService, DllStructGetPtr($tQB), DllStructGetSize($tQB))

    ; Get last error and close service handle
    If $avQB[0] = 0 Then $iQE = _WinAPI_GetLastError()
    CloseServiceHandle($hService)
    CloseServiceHandle($hSC)

    ; Decode the ubyte structure
    $tQC = DllStructCreate("dword[3];uint_ptr[2];dword;uint_ptr[3]", $avQB[2])

    Return SetError($iQE, 0, DllStructGetData($tQC, 1, 1))
EndFunc   ;==>_Service_QueryType



; #FUNCTION# =======================================================================================================================================================
; Name...........: _Service_Start
; Description ...: Starts a service.
; Syntax.........: _Service_Start($sServiceName [, $sComputerName])
; Parameters ....: $sServiceName - Name of the service.
;                  $sComputerName - [Optional] The name of the target computer. The local computer is default.
; Requirement(s).: Administrative rights on the target computer.
; Return values .: Success - 1
;                  Failure - 0
;                            Sets @error
; Author ........: engine
; Modified.......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......:
; ==================================================================================================================================================================

Func _Service_Start($sServiceName, $sComputerName = "")
    Local $hSC, $hService, $avSS, $iSS
    $hSC = OpenSCManager($sComputerName, $SC_MANAGER_CONNECT)
    $hService = OpenService($hSC, $sServiceName, $SERVICE_START)
    $avSS = DllCall($ghADVAPI32, "int", "StartServiceW", _
            "ptr", $hService, _
            "dword", 0, _
            "ptr", 0)
    If $avSS[0] = 0 Then $iSS = _WinAPI_GetLastError()
    CloseServiceHandle($hService)
    CloseServiceHandle($hSC)
    Return SetError($iSS, 0, $avSS[0])
EndFunc   ;==>_Service_Start



; #FUNCTION# =======================================================================================================================================================
; Name...........: _Service_Stop
; Description ...: Stops a service.
; Syntax.........: _Service_Stop($sServiceName [, $sComputerName])
; Parameters ....: $sServiceName - Name of the service.
;                  $sComputerName - [Optional] The name of the target computer. The local computer is default.
; Requirement(s).: Administrative rights on the target computer.
; Return values .: Success - 1
;                  Failure - 0
;                            Sets @error
; Author ........: engine
; Modified.......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......:
; ==================================================================================================================================================================

Func _Service_Stop($sServiceName, $sComputerName = "")
    Local $hSC, $hService, $iCSS, $iCSSE
    $hSC = OpenSCManager($sComputerName, $SC_MANAGER_CONNECT)
    $hService = OpenService($hSC, $sServiceName, $SERVICE_STOP)
    $iCSS = ControlService($hService, $SERVICE_CONTROL_STOP)
    If $iCSS = 0 Then $iCSSE = _WinAPI_GetLastError()
    CloseServiceHandle($hService)
    CloseServiceHandle($hSC)
    Return SetError($iCSSE, 0, $iCSS)
EndFunc   ;==>_Service_Stop



Func CloseServiceHandle($hSCObject)
    Local $avCSH = DllCall($ghADVAPI32, "int", "CloseServiceHandle", _
            "ptr", $hSCObject)
    If @error Then Return SetError(@error, 0, 0)
    Return $avCSH[0]
EndFunc   ;==>CloseServiceHandle



Func ControlService($hService, $iControl)
    Local $avCS = DllCall($ghADVAPI32, "int", "ControlService", _
            "ptr", $hService, _
            "dword", $iControl, _
            "ptr*", 0)
    If @error Then Return SetError(@error, 0, 0)
    Return $avCS[0]
EndFunc   ;==>ControlService



Func OpenSCManager($sComputerName, $iAccess)
    Local $avOSCM = DllCall($ghADVAPI32, "ptr", "OpenSCManagerW", _
            "wstr", $sComputerName, _
            "wstr", $SERVICES_ACTIVE_DATABASE, _
            "dword", $iAccess)
    If @error Then Return SetError(@error, 0, 0)
    Return $avOSCM[0]
EndFunc   ;==>OpenSCManager



Func OpenService($hSC, $sServiceName, $iAccess)
    Local $avOS = DllCall($ghADVAPI32, "ptr", "OpenServiceW", _
            "ptr", $hSC, _
            "wstr", $sServiceName, _
            "dword", $iAccess)
    If @error Then Return SetError(@error, 0, 0)
    Return $avOS[0]
EndFunc   ;==>OpenService



Func QueryServiceConfig($hService, $pServiceConfig, $iBufSize)
    Local $avQSC = DllCall($ghADVAPI32, "int", "QueryServiceConfigW", _
            "ptr", $hService, _
            "ptr", $pServiceConfig, _
            "dword", $iBufSize, _
            "dword*", 0)
    Return $avQSC
EndFunc   ;==>QueryServiceConfig



;~ Au3@Service routines by 'Arcker'. Modified by ShminkyBoy to include support for interactive services

Func _Service_Init($sServiceName)
    $service_type = _Service_QueryType($sServiceName)
    $tServiceCtrl = DllCallbackRegister("_Service_Ctrl", "dword", "dword;dword;ptr;ptr")
    $tServiceMain = DllCallbackRegister("_Service_ServiceMain", "none", "dword;ptr")
    $tdispatchTable = DllStructCreate("ptr[2];ptr[2]")
    $tServiceName = DllStructCreate("wchar[128]")
    DllStructSetData($tServiceName, 1, $sServiceName)
    DllStructSetData($tdispatchTable, 1, DllStructGetPtr($tServiceName), 1)
    DllStructSetData($tdispatchTable, 1, DllCallbackGetPtr($tServiceMain), 2)
    DllStructSetData($tdispatchTable, 2, 0, 1)
    DllStructSetData($tdispatchTable, 2, 0, 2)
    DllCall($ghADVAPI32, "int", "StartServiceCtrlDispatcherW", "ptr", DllStructGetPtr($tdispatchTable))
    ; cleanup callback resources
    DllCallbackFree($tServiceMain)
    DllCallbackFree($tServiceCtrl)
EndFunc   ;==>_Service_init



Func _Service_ServiceMain($iArg, $pArgs)
    Local $ret = DllCall($ghADVAPI32, "ptr", "RegisterServiceCtrlHandlerExW", "ptr", DllStructGetPtr($tServiceName), "ptr", DllCallbackGetPtr($tServiceCtrl), "ptr", 0) ;register service
    If @error Or ($ret[0] = 0) Then Exit
    $tService_Status_handle = $ret[0]
    If Not $tService_Status_handle Then
        _Service_Cleanup()
        Return
    EndIf

    DllStructSetData($tService_Status, "dwServiceType", $service_type)
    DllStructSetData($tService_Status, "dwServiceSpecificExitCode", 0)

    ; report the status to the service control manager.
    If Not (_Service_ReportStatus($SERVICE_START_PENDING, $NO_ERROR, 3000)) Then
        _Service_Cleanup()
        Return
    EndIf
    _Service_Startup($iArg, $pArgs)
    _Svc_Main()
EndFunc   ;==>_Service_ServiceMain



Func _Service_Cleanup()
    If $tService_Status_handle Then _Service_ReportStatus($SERVICE_STOPPED, $NO_ERROR, 0)
EndFunc   ;==>_Service_Cleanup



;/*------------------------------[ service_ctrl ]------------------------------
; *  Called by the SCM whenever ControlService() is called for this service
; *
; *  Parameters:
; *     ctrlCode - type of control requested
; *
; *  Return value:
; *     none
; *----------------------------------------------------------------------------*/
Func _Service_Ctrl($dwControl, $dwEventType, $lpEventData, $lpContext)
    #forceref $dwEventType, $lpEventData, $lpContext
    Local $return = $NO_ERROR
;~  WriteLog("_Service_Ctrl entered")
    Switch $dwControl
        Case $SERVICE_CONTROL_STOP
            ;stop the service.
            ;
            ;SERVICE_STOP_PENDING should be reported before
            ;setting the Stop Event - hServerStopEvent - in
            ;service_stop().  This avoids a race condition
            ;which may result in a 1053 - The Service did not respond...
            ;error.
            _Service_ReportStatus($SERVICE_STOP_PENDING, $NO_ERROR, 3000)
            _Service_SetStopEvent()
            ; call _Service_Cleanup() from _Svc_Main() immediately before exiting
            Return $NO_ERROR
        Case $SERVICE_CONTROL_PAUSE
            DllStructSetData($tService_Status, "dwCurrentState", $SERVICE_PAUSED)
        Case $SERVICE_CONTROL_CONTINUE
            DllStructSetData($tService_Status, "dwCurrentState", $SERVICE_RUNNING)
        Case $SERVICE_CONTROL_INTERROGATE
            ; report the service status
        Case $SERVICE_CONTROL_SESSIONCHANGE
            ; Extracting SessionID & cbSize
            Local $WTSSESSION_NOTIFICATION  = DllStructCreate("dword cbsize; dword dwSessionId", $lpEventData)
            Local $cbSize = DllStructGetData($WTSSESSION_NOTIFICATION, "cbSize")
            Local $dwSessionId = DllStructGetData($WTSSESSION_NOTIFICATION, "dwSessionId")
            WriteLog("cbSize = " & $cbSize & " ,dwSessionId = " & $dwSessionId)
            
            ;Trapping events
            Switch $dwEventType
                Case $WTS_CONSOLE_CONNECT
                    WriteLog("Console session connected", 0, 2)
                Case $WTS_CONSOLE_DISCONNECT
                    WriteLog("Console session disconnected", 0, 2)
                Case $WTS_REMOTE_CONNECT
                    WriteLog("Remote session connected", 0, 2)
                Case $WTS_REMOTE_DISCONNECT
                    WriteLog("Remote session disconnected", 0, 2)
                Case $WTS_SESSION_LOGON
                    WriteLog("Session logged on", 0, 2)
                Case $WTS_SESSION_LOGOFF
                    WriteLog("Session logged off", 0, 2)
                Case $WTS_SESSION_LOCK
                    WriteLog("Session locked", 0, 2)
                Case $WTS_SESSION_UNLOCK
                    WriteLog("Session unlocked", 0, 2)
                Case $WTS_SESSION_REMOTE_CONTROL
                    WriteLog("Session remote control", 0, 2)
            EndSwitch       
        Case 128 To 255 ; custom messages
            ; handle custom messages
        Case Else
            ; invalid or unhandled control code
            $return = $ERROR_CALL_NOT_IMPLEMENTED
    EndSwitch
    _Service_ReportStatus(DllStructGetData($tService_Status, "dwCurrentState"), $NO_ERROR, 0)
    Return $return
EndFunc   ;==>_Service_Ctrl



;/*--------------------------[ _Service_ReportStatus ]--------------------------
; *  Sets the current status and reports it to the Service Control Manager
; *
; *  Parameters:
; *     currentState    -  the state of the service
; *     exitCode        -  error code to report
; *     waitHint        -  worst case estimate to next checkpoint
; *
; *  Return value:
; *     true            -  success
; *     false           -  failure
; *----------------------------------------------------------------------------*/
Func _Service_ReportStatus($currentState, $exitCode, $waitHint)
    Local $rc = True
    If Not $service_debug_mode Then ;when debugging we don't report to the SCM
        If ($currentState = $SERVICE_START_PENDING) Then
            DllStructSetData($tService_Status, "dwControlsAccepted", 0)
        Else
;~          WriteLog("_Service_ReportStatus entered")
            DllStructSetData($tService_Status, "dwControlsAccepted", BitOR($SERVICE_ACCEPT_STOP, $SERVICE_ACCEPT_SESSIONCHANGE))
        EndIf

        DllStructSetData($tService_Status, "dwCurrentState", $currentState)
        DllStructSetData($tService_Status, "dwWin32ExitCode", $exitCode)
        DllStructSetData($tService_Status, "dwWaitHint", $waitHint)
        If ($currentState = $SERVICE_RUNNING) Or ($currentState = $SERVICE_STOPPED) Then
            DllStructSetData($tService_Status, "dwCheckPoint", 0)
        Else
            $gdwCheckPoint += 1
            DllStructSetData($tService_Status, "dwCheckPoint", $gdwCheckPoint)
        EndIf
        ; report the status of the service to the service control manager.
        $rc = _Service_SetServiceStatus($tService_Status_handle, DllStructGetPtr($tService_Status))
    EndIf
    Return $rc
EndFunc   ;==>_Service_ReportStatus



Func _Service_SetServiceStatus($hServiceStatus, $lpServiceStatus)
    Local $ret = DllCall($ghADVAPI32, "int", "SetServiceStatus", "ptr", $hServiceStatus, "ptr", $lpServiceStatus)
    If @error Or Not $ret[0] Then Return 0
    Return $ret[0]
EndFunc   ;==>_Service_SetServiceStatus



;/*------------------------------[ service_start ]------------------------------
; * Starts and runs the service
; *----------------------------------------------------------------------------*/

Func _Service_Startup($argc, $argv)
    ; report the status to the service control manager.
    If Not _Service_ReportStatus($SERVICE_START_PENDING, $NO_ERROR, 3000) Then Return
    ; create the event object. The control handler function signals
    ; this event when it receives the "stop" control code.
    $gServiceStateRunning = 1
    $service_stop_event = _WinAPI_CreateEvent(0, True, False, "")
    ; report the status to the service control manager.
    Return _Service_ReportStatus($SERVICE_RUNNING, $NO_ERROR, 0)
EndFunc   ;==>_Service_Startup



;/*------------------------------[ service_stop ]------------------------------
; * Stops the service.
; *
; * NOTE: If this service will take longer than 3 seconds,
; * spawn a thread to execute the stop code and return.
; * Otherwise the SCM will think the service has stopped responding.
; *----------------------------------------------------------------------------*/

Func _Service_SetStopEvent()
    $gServiceStateRunning = 0
    If $service_stop_event Then _WinAPI_SetEvent($service_stop_event)
EndFunc   ;==>_Service_SetStopEvent

this is the main script using the UDF:

#include "WinAPIEx.au3"

#include "Log.au3"
#include "Misc.au3"
#include "Services.au3"


Global $sServiceName = "SessionChange"
Global $sServiceDisplayName = "SessionChange"



If Not @Compiled Then Exit
If Not _Singleton(@ScriptName) Then
    If $cmdline[0] > 0 Then
        If $cmdline[1] = "stop" or StringRight($cmdline[1],1) = "s" Then
        Else
            MsgBox(0, "SessionChange", "Process is running.")
            WriteLog("Process is running.")
            Exit
        EndIf
    Else
        MsgBox(0, "SessionChange", "Process is running.")
        WriteLog("Process is running.")
        Exit
    EndIf
EndIf



If $cmdline[0] > 0 Then
    Switch $cmdline[1]
        Case "install", "-i", "/i"
            InstallService()
        Case "remove", "-u", "/u", "uninstall"
            RemoveService()
        Case "run", "-r", "/r", "start"
            _SelfRun($sServiceName,"start")
        Case "stop", "-s", "/s"
            _SelfRun($sServiceName,"stop")
        Case Else
            WriteLog(" - - - Help - - - " & @crlf)
            WriteLog(" Service Example Params : " & @crlf)
            WriteLog("  -i : Installs service" & @crlf)
            WriteLog("  -u : Removes service" & @crlf)
            WriteLog("  -r : Runs the service" & @crlf)
            WriteLog("  -s : Stops the service" & @crlf)
            WriteLog(" - - - - - - - - " & @crlf)
            Exit
    EndSwitch

Else
    If Not _Service_Exists($sServiceName) Then
        If Msgbox(20,"Service Not Installed.","Would you like to install this service?" & @CRLF & $sServiceName) = 6 Then
            If InstallService() Then
                If Msgbox(4,$sServiceName,"Service Installed Successfully." & @CRLF & "Do you wish to start the process?") = 6 Then _SelfRun($sServiceName,"start")
            EndIf
        Else
            Exit
        EndIf
    EndIf
EndIf



_Service_Init($sServiceName)



Func _Svc_Main()
    WriteLog("Service started: SessionChange")

    While $gServiceStateRunning
        Sleep(1000)
        If @SEC/3=Round(@SEC/3) Then FileWriteLine('C:\TEMP\parent.txt',@SEC&' '&_WinAPI_GetProcessFileName(_WinAPI_GetParentProcess(@AutoItPID)))
    WEnd

    _Service_Cleanup()
    WriteLog("Service stopped: SessionChange")
EndFunc



Func InstallService()
;~  Set Logfile path
    RegWrite("HKEY_LOCAL_MACHINE\Software\SessionChange", "LogfilePath", "REG_SZ", @ScriptDir)
    $LogfilePath = @TempDir

;~  Check for Adminstrativee rights
    If Not(IsAdmin()) Then
        MsgBox(0, "SessionChange", "Admin rights needed, will exit now")
        WriteLog("Admin rights needed, will exit now")
        Exit
    EndIf

    WriteLog("Installing Service, Please Wait" & @CRLF)
    _Service_Create($sServiceName,$sServiceDisplayName,$SERVICE_WIN32_OWN_PROCESS,$SERVICE_AUTO_START, $SERVICE_ERROR_SEVERE, '"' & @SystemDir & '\' & @ScriptName & '"')

    If @error Then
        WriteLog("Problem Installing Service, Error number is " & @error & @CRLF & " message  : " & _WinAPI_GetLastErrorMessage())
        Return 0
    Else
        WriteLog("Installation of Service Successful")
    EndIf

    FileCopy(@ScriptName, @SystemDir & '\' & @ScriptName, 1)

    Return 1
    Exit
EndFunc



Func RemoveService()
    _Service_Stop($sServiceName)
    _Service_Delete($sServiceName)
    if not @error then WriteLog("Service Removed Successfully" & @crlf)
    Exit
EndFunc



Func _SelfRun($servicename,$action)
    $sCmdFile = 'sc ' & $action & ' "' & $servicename & '"'
    Run($sCmdFile, @TempDir, @SW_HIDE)
    Exit
EndFunc

and this is the "log.au3" dependency for the UDF:

#include-once 

Global $LogFile = "SessionChange" & "_" & @MDAY & "." & @MON & "." & @YEAR & " _ " & @HOUR & "." & @MIN & "." & @SEC & ".log"
Global $LogfilePath = RegRead("HKEY_LOCAL_MACHINE\Software\SessionChange", "LogfilePath")
Global $hLogFile = FileOpen($LogfilePath & '\' & $LogFile, 1)
WriteLog("", 1)

Func WriteLog($text, $isNewLogFile = 0, $isCRLF = 0)
    Dim $Months[12]
    $Months[0] = "January"
    $Months[1] = "February"
    $Months[2] = "March"
    $Months[3] = "April"
    $Months[4] = "May"
    $Months[5] = "June"
    $Months[6] = "July"
    $Months[7] = "August"
    $Months[8] = "September"
    $Months[9] = "October"
    $Months[10] = "November"
    $Months[11] = "December"
    
    If @HOUR > 12 Then
        $Hour = @HOUR - 12
        $HourSuffix = " PM"
    Else
        $Hour = @HOUR
        $HourSuffix = " AM"
    EndIf
    
    If $isNewLogFile = 1 Then
        Local $FormatString = "Log created: " & $Months[@MON - 1] & " " & @MDAY &", " & @YEAR & " : " & $Hour & ":" & @MIN & ":" & @SEC & $HourSuffix
        DrawLine(StringLen($FormatString), '_')
        FileWriteLine($hLogFile, $FormatString)
        DrawLine(StringLen($FormatString), '_')
        FileWriteLine($hLogFile, @CRLF & @CRLF)
    Else
        Local $FormatString = ''
        For $index = 1 To $isCRLF
            $FormatString = $FormatString & @CRLF
        Next
        $FormatString = $FormatString & $Months[@MON - 1] & " " & @MDAY & ", " & @YEAR & " : " & $Hour & ":" & @MIN & ":" & @SEC & $HourSuffix & " [" & @AutoItPID & "] >> " & $text
        FileWriteLine($hLogFile, $FormatString)
    EndIf
EndFunc



Func DrawLine($Count, $Character)
    Local $FormatString = ''
    For $index = 1 To $Count
        $FormatString = $FormatString & $Character
    Next
    FileWriteLine($hLogFile, $FormatString)
EndFunc

EDIT: and this is the constants file:

#include-once

; Standard access rights for a service
Global Const $SERVICES_ACTIVE_DATABASE = "ServicesActive"
Global Const $DELETE = 0x10000

#cs
Global Const $READ_CONTROL = 0x20000
Global Const $WRITE_DAC = 0x40000
Global Const $WRITE_OWNER = 0x80000

Global Const $STANDARD_RIGHTS_REQUIRED = BitOR( $DELETE, _
                                        $READ_CONTROL, _
                                        $WRITE_DAC, _
                                        $WRITE_OWNER )
#ce
; Access rights for the Service Control Manager
Global Const $SC_MANAGER_CONNECT = 0x0001
Global Const $SC_MANAGER_CREATE_SERVICE = 0x0002
Global Const $SC_MANAGER_ENUMERATE_SERVICE = 0x0004
Global Const $SC_MANAGER_LOCK = 0x0008
Global Const $SC_MANAGER_QUERY_LOCK_STATUS = 0x0010
Global Const $SC_MANAGER_MODIFY_BOOT_CONFIG = 0x0020

Global Const $SC_MANAGER_ALL_ACCESS = 0xF003F
;~ BitOR( $STANDARD_RIGHTS_REQUIRED, _
;~ $SC_MANAGER_CONNECT, _
;~ $SC_MANAGER_CREATE_SERVICE, _
;~ $SC_MANAGER_ENUMERATE_SERVICE, _
;~ $SC_MANAGER_LOCK, _
;~ $SC_MANAGER_QUERY_LOCK_STATUS, _
;~ $SC_MANAGER_MODIFY_BOOT_CONFIG)

; Access rights for a service
Global Const $SERVICE_QUERY_CONFIG = 0x0001
Global Const $SERVICE_CHANGE_CONFIG = 0x0002
Global Const $SERVICE_QUERY_STATUS = 0x0004
Global Const $SERVICE_ENUMERATE_DEPENDENTS = 0x0008
Global Const $SERVICE_START = 0x0010
Global Const $SERVICE_STOP = 0x0020
Global Const $SERVICE_PAUSE_CONTINUE = 0x0040
Global Const $SERVICE_INTERROGATE = 0x0080
Global Const $SERVICE_USER_DEFINED_CONTROL = 0x0100

Global Const $SERVICE_ALL_ACCESS = 0xF01FF
;~ BitOR( $STANDARD_RIGHTS_REQUIRED, _
;~ $SERVICE_QUERY_CONFIG, _
;~ $SERVICE_CHANGE_CONFIG, _
;~ $SERVICE_QUERY_STATUS, _
;~ $SERVICE_ENUMERATE_DEPENDENTS, _
;~ $SERVICE_START, _
;~ $SERVICE_STOP, _
;~ $SERVICE_PAUSE_CONTINUE, _
;~ $SERVICE_INTERROGATE, _
;~ $SERVICE_USER_DEFINED_CONTROL)

; Service controls
Global Const $SERVICE_CONTROL_STOP = 0x00000001
Global Const $SERVICE_CONTROL_PAUSE = 0x00000002
Global Const $SERVICE_CONTROL_CONTINUE = 0x00000003
Global Const $SERVICE_CONTROL_INTERROGATE = 0x00000004
Global Const $SERVICE_CONTROL_SHUTDOWN = 0x00000005
Global Const $SERVICE_CONTROL_PARAMCHANGE = 0x00000006
Global Const $SERVICE_CONTROL_NETBINDADD = 0x00000007
Global Const $SERVICE_CONTROL_NETBINDREMOVE = 0x00000008
Global Const $SERVICE_CONTROL_NETBINDENABLE = 0x00000009
Global Const $SERVICE_CONTROL_NETBINDDISABLE = 0x0000000A
Global Const $SERVICE_CONTROL_DEVICEEVENT = 0x0000000B
Global Const $SERVICE_CONTROL_HARDWAREPROFILECHANGE = 0x0000000C
Global Const $SERVICE_CONTROL_POWEREVENT = 0x0000000D
Global Const $SERVICE_CONTROL_SESSIONCHANGE = 0x0000000E

; Service event types
Global Const $WTS_CONSOLE_CONNECT = 0x00000001
Global Const $WTS_CONSOLE_DISCONNECT = 0x00000002
Global Const $WTS_REMOTE_CONNECT = 0x00000003
Global Const $WTS_REMOTE_DISCONNECT = 0x00000004
Global Const $WTS_SESSION_LOGON = 0x00000005
Global Const $WTS_SESSION_LOGOFF = 0x00000006
Global Const $WTS_SESSION_LOCK = 0x00000007
Global Const $WTS_SESSION_UNLOCK = 0x00000008
Global Const $WTS_SESSION_REMOTE_CONTROL = 0x00000009

; Service config
Global Const $SERVICE_NO_CHANGE = -1
Global Const $SERVICE_CONFIG_DESCRIPTION = 1
Global Const $SERVICE_CONFIG_FAILURE_ACTIONS = 2

; Service types
Global Const $SERVICE_KERNEL_DRIVER = 0x00000001
Global Const $SERVICE_FILE_SYSTEM_DRIVER = 0x00000002
Global Const $SERVICE_ADAPTER = 0x00000004
Global Const $SERVICE_RECOGNIZER_DRIVER = 0x00000008
Global Const $SERVICE_DRIVER = BitOR( $SERVICE_KERNEL_DRIVER, _
                            $SERVICE_FILE_SYSTEM_DRIVER, _
                            $SERVICE_RECOGNIZER_DRIVER )
Global Const $SERVICE_WIN32_OWN_PROCESS = 0x00000010
Global Const $SERVICE_WIN32_SHARE_PROCESS = 0x00000020
Global Const $SERVICE_WIN32 = BitOR( $SERVICE_WIN32_OWN_PROCESS, _
                            $SERVICE_WIN32_SHARE_PROCESS )
Global Const $SERVICE_INTERACTIVE_PROCESS = 0x00000100
Global Const $SERVICE_TYPE_ALL = BitOR( $SERVICE_WIN32, _
                                $SERVICE_ADAPTER, _
                                $SERVICE_DRIVER, _
                                $SERVICE_INTERACTIVE_PROCESS )

; Service start types
Global Const $SERVICE_BOOT_START = 0x00000000
Global Const $SERVICE_SYSTEM_START = 0x00000001
Global Const $SERVICE_AUTO_START = 0x00000002
Global Const $SERVICE_DEMAND_START = 0x00000003
Global Const $SERVICE_DISABLED = 0x00000004

; Service error control
Global Const $SERVICE_ERROR_IGNORE = 0x00000000
Global Const $SERVICE_ERROR_NORMAL = 0x00000001
Global Const $SERVICE_ERROR_SEVERE = 0x00000002
Global Const $SERVICE_ERROR_CRITICAL = 0x00000003

; Service state
Global Const $SERVICE_STOPPED = 0x00000001
Global Const $SERVICE_START_PENDING = 0x00000002
Global Const $SERVICE_STOP_PENDING = 0x00000003
Global Const $SERVICE_RUNNING = 0x00000004
Global Const $SERVICE_CONTINUE_PENDING = 0x00000005
Global Const $SERVICE_PAUSE_PENDING = 0x00000006
Global Const $SERVICE_PAUSED = 0x00000007

; Service accept control codes
Global Const $SERVICE_ACCEPT_STOP = 0x00000001
Global Const $SERVICE_ACCEPT_PAUSE_CONTINUE = 0x00000002
Global Const $SERVICE_ACCEPT_SHUTDOWN = 0x00000004
Global Const $SERVICE_ACCEPT_PARAMCHANGE = 0x00000008
Global Const $SERVICE_ACCEPT_NETBINDCHANGE = 0x00000010
Global Const $SERVICE_ACCEPT_HARDWAREPROFILECHANGE = 0x00000020
Global Const $SERVICE_ACCEPT_POWEREVENT = 0x00000040
Global Const $SERVICE_ACCEPT_SESSIONCHANGE = 0x00000080
Global Const $SERVICE_ACCEPT_PRESHUTDOWN = 0x00000100

; Service enumerate
Global Const $SERVICE_ACTIVE = 0x00000001
Global Const $SERVICE_INACTIVE = 0x00000002
Global Const $SERVICE_STATE_ALL = BitOR( $SERVICE_ACTIVE, _
                                $SERVICE_INACTIVE )

; Service info
Global Const $SC_STATUS_PROCESS_INFO = 0
Global Const $SC_ENUM_PROCESS_INFO = 0

; Service specific system error codes
Global Const $ERROR_CALL_NOT_IMPLEMENTED = 120
Global Const $ERROR_SERVICE_DISABLED = 1058
Global Const $ERROR_SERVICE_SPECIFIC_ERROR = 1066
Global Const $ERROR_SERVICE_DEPENDENCY_FAIL = 1068
Global Const $ERROR_SERVICE_NEVER_STARTED = 1077
Global Const $NO_ERROR = 0

; SC_ACTION_TYPE enumeration type
Global Enum $SC_ACTION_NONE, $SC_ACTION_RESTART, $SC_ACTION_REBOOT, $SC_ACTION_RUN_COMMAND

Global Const $SERVICE_RUNS_IN_SYSTEM_PROCESS = 0x00000001

; Globals for Au3@service routines
Global $tServiceName, $tServiceCtrl, $tServiceMain, $tdispatchTable, $service_debug_mode = False
Global $tService_Status = DllStructCreate("dword dwServiceType;" & _
        "dword dwCurrentState;dword dwControlsAccepted;dword dwWin32ExitCode;" & _
        "dword dwServiceSpecificExitCode;dword dwCheckPoint;dword dwWaitHint")
Global $tService_Status_handle
Global Const $NTSL_LOOP_WAIT = -1
Global $service_type
Global $service_stop_event
Global $NTSL_ERROR_SERVICE_STATUS = 2
Global Const $WAIT_OBJECT_0 = 0x0
Global $gdwCheckPoint = 1
Global $ghADVAPI32 = DllOpen("advapi32.dll")
Global $gServiceStateRunning
Edited by orbs

Share this post


Link to post
Share on other sites

@orbs

Thx for the report.

I'm trying to make a new version since i need it too now and I wonder how i could post a so messy bad code for v4 ...
I can't reprodude the problem you have with dependencies : my service works well even if i go to dependencies tab.
The current service example couldn't install the service ( at least, i've commented the install mode, but it wasn't enabled by default )

I'm reworking on it. BTW WINXP isn't supported anymore.

It last code i posted wasnt the last code we manage to get with the help of bitboy.

Can you download those ones ? :

 

ServiceExample_v4.au3

Services.au3

Edited by arcker

-- Arck System _ Soon -- Ideas make everything

"La critique est facile, l'art est difficile"

Projects :

[list] [*]Au3Service : Run your exe as service V3 / Updated 29/07/2013 Get it Here [/list]

Share this post


Link to post
Share on other sites

found a weird bug when service is launched with net start / net stop
It's a bug with RegisterServiceCtrlHandlerEx
No problem when when run from service console

I'll try to fix it or I back to the simple ( but working and needed for 90% of users ) RegisterServiceCtrlHandler ...


-- Arck System _ Soon -- Ideas make everything

"La critique est facile, l'art est difficile"

Projects :

[list] [*]Au3Service : Run your exe as service V3 / Updated 29/07/2013 Get it Here [/list]

Share this post


Link to post
Share on other sites

Just an FYI:
I added the ability to add the description in the "_Service_Create" function.  I just added a new optional param "$sDescription = Default" and plopped this bit of code in the function.

        ;## Set Description
        If $sDescription <> Default Then
            Local $serviceDescription = DllStructCreate("ptr")
            Local $caDescription = DllStructCreate("char[260]")
            DllStructSetData($caDescription, 1, $sDescription)
            DllStructSetData($serviceDescription, 1, DllStructGetPtr($caDescription))
            DllCall($hAdvapi32_DLL, "int", "ChangeServiceConfig2", "long", $avSC[0], "long", 1, "long", DllStructGetPtr($serviceDescription))
        EndIf
        CloseServiceHandle($avSC[0]) ;<-- Line that already exists in function

Works great for me.  ^u^

​I've added to v5 ( with your name on it ) , thx for that :)


-- Arck System _ Soon -- Ideas make everything

"La critique est facile, l'art est difficile"

Projects :

[list] [*]Au3Service : Run your exe as service V3 / Updated 29/07/2013 Get it Here [/list]

Share this post


Link to post
Share on other sites

just played around with pause and continue, and seems to work well.
Will be added in service example v5

Custom code can be added too, can be useful for interaction within the service ?
 


-- Arck System _ Soon -- Ideas make everything

"La critique est facile, l'art est difficile"

Projects :

[list] [*]Au3Service : Run your exe as service V3 / Updated 29/07/2013 Get it Here [/list]

Share this post


Link to post
Share on other sites

One of my customers has stil the problem with stopping service...

OS: WinServer'08R2 x64 and Win7 x64

Services.au3 V4

My _Main-Func :

Func _Main($iArg, $sArgs)
    #Region -- STOP -- Service Start
    If $bDebug Then Debug("***** SERVICE START *******")
    If Not _Service_ReportStatus($SERVICE_RUNNING, $NO_ERROR, 0) Then
        If $bAU3ServiceDebug Then logprint("Error sending running status, exiting")
        _Service_ReportStatus($SERVICE_STOPPED, _WinAPI_GetLastError(), 0)
        Exit
    EndIf
    _Service_ReportStatus($SERVICE_START_PENDING, $NO_ERROR, 10)
    _Service_ReportStatus($SERVICE_RUNNING, $NO_ERROR, 30)

    If $bDebug Then Debug("Started Main.")

    $bServiceRunning = True
    #EndRegion -- STOP -- Service Start
    While $bServiceRunning ; REQUIRED  ( dont change variable name ) ; there are several ways to find that service have to be stoped - $Running flag in loop is the first method

        #Region --> mycode
        _Service_ReportStatus($SERVICE_RUNNING, $NO_ERROR, 30)
        If Not $bServiceRunning Then
            logprint("Service stopped!")
            TCPShutdown()
            ProcessClose(@AutoItPID)
            ExitLoop
        EndIf
        USleep(5000, $NTDLL) ;This is needed because TCPTimeout is disabled. Without this it will run one core at ~100%.
        ;The USleep function takes MICROseconds, not milliseconds, so 1000 = 1ms delay.
        ;When working with this granularity, you have to take in to account the time it takes to complete USleep().
        ;1000us (1ms) is about as fast as this should be set. If you need more performance, set this from 5000 to 1000,
        ;but doing so will make it consume a bit more CPU time to get that extra bit of performance.
        Check() ;Check recv buffers and do things´
        If TimerDiff($CleanupTimer) > 1000 Then ;If it has been more than 1000ms since Cleanup() was last called, call it now
            $CleanupTimer = TimerInit() ;Reset $CleanupTimer, so it is ready to be called again
            Cleanup() ;Clean up the dead connections
        EndIf
        Local $iSock = TCPAccept($Listen) ;See if anything wants to connect
        If $iSock = -1 Then ContinueLoop ;If nothing wants to connect, restart at the top of the loop
        Local $iSize = UBound($Clients, 1) ;Something wants to connect, so get the number of people currently connected here
        If $iSize - 1 > $MaxClients And $MaxClients > 0 Then ;If $MaxClients is greater than 0 (meaning if there is a max connection limit) then check if that has been reached
            TCPCloseSocket($iSock) ;It has been reached, close the new connection and continue back at the top of the loop
            ContinueLoop
        EndIf
        ReDim $Clients[$iSize + 1][4] ;There is room for a new connection, allocate space for it here
        $Clients[0][0] = $iSize ;Update the number of connected clients
        $Clients[$iSize][0] = $iSock ;Set the socket ID of the connection
        $Clients[$iSize][1] = SocketToIP($iSock, $Ws2_32) ;Set the IP Address the connection is from
        $Clients[$iSize][2] = TimerInit() ;Set the timestamp for the last known activity timer
        $Clients[$iSize][3] = "" ;Blank the recv buffer
        #EndRegion --> mycode
    WEnd
    _Service_ReportStatus($SERVICE_STOP_PENDING, $NO_ERROR, 1000)
    DllCallbackFree($tServiceMain)
    DllCallbackFree($tServiceCtrl)
    _Service_ReportStatus($SERVICE_STOPPED, $NO_ERROR, 0)
    DllClose($hAdvapi32_DLL)
    DllClose($hKernel32_DLL)
    Sleep(1000)
    ProcessClose(@AutoItPID)
    Return
EndFunc   ;==>_Main


Can someone help me please?
 

Share this post


Link to post
Share on other sites

is there a way to show dialogs if script is running as service using Security.au3? 
help file of  "_Security__CreateProcessWithToken" maybe have a solution but I cant get it to work, is the Func _RunNonElevated() only intended for when #RequireAdmin is used?
 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By SgtHugoStiglitz
      HI people,
                        I got a questions, I maintain code in autoIT and every time I compile a new version or modification, Scite generate 2 folders. One folder is finish by released and the other is tentative. I try to make some google search, but never find answer would satisfied myself. The dev who was maintain it before were using AutoIt3Wrapper_GUI, and I don't know if it's related. I look both folder, but they seem pretty identical, but I would like to know what it's the difference between those to folder. Anyone have a clue?
    • By Rhidlor
      I don't have any experience compiling AutoIt scripts or know of any best practices regarding said scripts so I was wondering, what are some of the options for passing data to complied scripts? Here's an example of what I mean by "option": Writing data to a text file, then running a script which reads the data from that text file.
      Thanks!
      I apologize if this topic is a little lackluster
    • By Skeletor
      Hey All,
      Yes, this is an odd request. 
      But is there a way to bulk up the size of the compiled program? 
      I know many want to reduce it's size, but I want to increase it.
      What methods do you suggest?
    • By dimm
      Is it possible to compile script without any icon resources included?
      When I make exe it uses default system icon of current OS even if I compile as console application.
      On other versions of Windows it looks a little strange

       
      Update:
      It seems that the only way is remove icons from exe after compilation using resource editors like ResHacker.

       
      another bad solution:
      Using corrupted 35 bytes icon file. Windows can't load it and shows default system icon.
      #pragma compile(Icon, broken.ico) broken.ico
    • By Dreamfire
      Hi,
      Since today, exe's are being flagged as having a trojan by Windows Defender (Fuery.B!cl)
      Version:  3.3.14.3 - SciTE Version 3.7.3



       

×
×
  • Create New...