Jump to content

_Service_UDF v4 : Build your own service with autoit code


arcker
 Share

Recommended Posts

I've not followed so well the different problems.

As I said in my first post, services are not fully compatible with GUI or others functions

that will concern window session ( instead of window station )

Since there, you can post your script since we can understand what's happening, but

respecting the MSDN, I won't provide support for scripts that have GUIs or other advanced functions

not destinated to a service application.

-- 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]
Link to comment
Share on other sites

  • 3 weeks later...

Hello arcker

you have made a really good job here, and I decided to use your UDF to create an "agent".

This agent is supposed to wait orders threw TCP/IP socket, and by receving particular coded orders, take somme actions like :

- returning current date

- returning boot date

- reboot or power-off

I installed the agent on about 15 differents computers , but like modie, I have "no response" problems after a while, and only on part of this computers.

When the problems appears, I want to stop and restart the service, but I get the message "could not stop the Agentsupervision service on local computer.Error 997: Overlapped I/O operation is in progress".

I can get the agent working again by stop and restart the service, but each time I stop the service, I will get the same message, even if the service responds to my requests just before...

It's impossible to remove the service without rebooting : I get the response "service marked for deletion" when trying to remove.

working computers:

- W2003R2 SP2

- W2000

- W2003R2 SP1

- W2000 SP4

- W2008 SP1

-

bugging computers:

- W2000 SP4

- W2003 SP1

Here is the code I wrote for the "agent".

;
; programme à l'écoute des ordres 
;
;
#include <File.au3>
; necessaire pour Installer et retirer le service 'Agentsupervision '
#include "Service.au3"

; desactiver l'icone Autoit dans la systray:
AutoItSetOption("TrayIconHide", 1)


$LOGFILE = StringTrimRight(@ScriptFullPath, 4) & ".log"

; Function to return IP Address from a connected socket.
;----------------------------------------------------------------------
Func SocketToIP($SHOCKET)
    Local $sockaddr, $aRet

    $sockaddr = DllStructCreate("short;ushort;uint;char[8]")

    $aRet = DllCall("Ws2_32.dll", "int", "getpeername", "int", $SHOCKET, _
            "ptr", DllStructGetPtr($sockaddr), "int*", DllStructGetSize($sockaddr))
    If Not @error And $aRet[0] = 0 Then
        $aRet = DllCall("Ws2_32.dll", "str", "inet_ntoa", "int", DllStructGetData($sockaddr, 3))
        If Not @error Then $aRet = $aRet[0]
    Else
        $aRet = 0
    EndIf

    $sockaddr = 0

    Return $aRet
EndFunc   ;==>SocketToIP


;
; Programme principal
;
If FileGetSize($LOGFILE) > 500000 Then
    FileMove($LOGFILE, $LOGFILE & ".old", 1)
EndIf

;
; Installation et desinstallation du service...
;
$NOMSERVICE = "AgentSupervision"
If $CMDLINE[0] = 1 Then
    Switch $CMDLINE[1]
        Case "install", "-i", "/i"
            _Service_Create("", $NOMSERVICE, $NOMSERVICE, '"' & @ScriptFullPath & '"')
            If @error Then
                _FileWriteLog($LOGFILE,"Erreur d'installation du service,err= " & @error & @CRLF & " message  : " & _WinAPI_GetLastErrorMessage())
            Else
                _FileWriteLog($LOGFILE,"Installation du service reussie")
            EndIf
            sleep(1000)
            _Service_Start("", $NOMSERVICE)
            If @error Then
                _FileWriteLog($LOGFILE,"Erreur d'activation du service,err= " & @error & @CRLF & " message  : " & _WinAPI_GetLastErrorMessage())
            Else
                _FileWriteLog($LOGFILE,"démarrage du service reussi")
            EndIf

        Case "remove", "-u", "/u", "uninstall"
            _StopService("", $NOMSERVICE)
            _DeleteService("", $NOMSERVICE)
            If @error Then
                _FileWriteLog($LOGFILE,"Erreur pendant suppression du service,err= " & @error & @CRLF & " message  : " & _WinAPI_GetLastErrorMessage())
            Else
                _FileWriteLog($LOGFILE,"service supprimmé" & @CRLF)
            EndIf

        Case Else
            _FileWriteLog($LOGFILE," - - - Aide - - - " & @CRLF)
            _FileWriteLog($LOGFILE,"parametress : " & @CRLF)
            _FileWriteLog($LOGFILE,"  -i : install service" & @CRLF)
            _FileWriteLog($LOGFILE,"  -u : remove service" & @CRLF)
            _FileWriteLog($LOGFILE," - - - - - - - - " & @CRLF)
    EndSwitch
    Exit 0 ; par sécurité
EndIf


_Service_init($NOMSERVICE)
exit 0 ; par sécurité

Func main()

    ; Récupération du boot time ( qui ne change pas tant que ce programme vit)
    $objWMIService = ObjGet("winmgmts:\\" & @ComputerName & "\root\cimv2")
    $colOperatingSystems = $objWMIService.ExecQuery("Select * from Win32_OperatingSystem")
    $LASTBOOTTIME = ""
    For $objOperatingSystem In $colOperatingSystems
        ;;  $objSWbemDateTime = ObjCreate("WbemScripting.SWbemDateTime")
        ;;  $objSWbemDateTime.Value = $objOperatingSystem.LastBootUpTime
        ;;  MsgBox(0,"Last boot time:",$objSWbemDateTime.GetVarDate  & @CRLF & "test:" & $objOperatingSystem.LastBootUpTime )
        $LASTBOOTTIME = StringLeft($objOperatingSystem.LastBootUpTime, 14)
    Next

    ;

    TCPStartup()
    $MainSocket = TCPListen(@IPAddress1, 33891)
    If $MainSocket = -1 Then
        _FileWriteLog($LOGFILE,"Activation de l'écoute sur le port 33891 impossible:port occupé?")
        Exit 8
    EndIf
    ; Initialize a variable to represent a connection
    ;==============================================
    $ConnectedSocket = -1

    ; boucle infinie : soit on écoute , soit on agit.
    While 1


        ;Wait for and Accept a connection
        ;==============================================
        $CPT=0
        Do
            $ConnectedSocket = TCPAccept($MainSocket)
            $CPT+=1
            sleep(10)
        Until $ConnectedSocket <> -1


        ; Get IP of client connecting
        $szIP_Accepted = SocketToIP($ConnectedSocket)
        _FileWriteLog($LOGFILE, "Connexion entrante " & $szIP_Accepted & ",CPT=" & $CPT )
        $TEXTERECU = TCPRecv($ConnectedSocket, 2048)
        If $TEXTERECU <> "" Then
            if StringLeft($szIP_Accepted,7)="10.20.0" Then
                Switch $TEXTERECU
                    Case "TESTDATE"
                        $TEXTEREPONSE = @YEAR & @MON & @MDAY & @HOUR & @MIN & @SEC
                        _FileWriteLog($LOGFILE, "Date demandée")
                    Case "TESTVOS"
                        $TEXTEREPONSE = @OSTYPE & " " & @OSVersion
                        _FileWriteLog($LOGFILE, "Version OS demandée")
                    Case "TESTLBOOT"
                        $TEXTEREPONSE = $LASTBOOTTIME
                        _FileWriteLog($LOGFILE, "Lastboottime demandée")
                    Case "TESTRBOOT"
                        _FileWriteLog($LOGFILE, "Reboot")
                        $TEXTEREPONSE = 1 - Shutdown(7) ; retourne 1 si KO, et 0 si OK accepté
                    Case "TESTPWOFF"
                        _FileWriteLog($LOGFILE, "Poweroff")
                        $TEXTEREPONSE = 1 - Shutdown(13) ; retourne 1 si KO, et 0 si OK accepté
                    Case Else
                        $TEXTEREPONSE = "UNKNOWN REQUEST"
                        _FileWriteLog($LOGFILE,"UNKNOWN REQUEST:" & $TEXTERECU)
                EndSwitch
            Else
                $TEXTEREPONSE = "YOU ARE NOT AUTHORIZED"
                _FileWriteLog($LOGFILE,"NOT AUTHORIZED:" & $TEXTERECU)
            EndIf
            TCPSend($ConnectedSocket, $TEXTEREPONSE)
        EndIf
        sleep(100) ; pour lui laisser le temps d'envoyer la réponse, au cas où...
        ; fermeture du dialogue
        If $ConnectedSocket <> -1 Then
            _FileWriteLog($LOGFILE,"Fermeture connexion " & $szIP_Accepted)
            TCPCloseSocket($ConnectedSocket)
        Else
            _FileWriteLog($LOGFILE,"Erreur pendant dialogue " & $szIP_Accepted)
        EndIf

    WEnd
EndFunc   ;==>main

I decided to reinstall service with "SC" instead of "autoinstall" feature that I have wrote in the script, but this have not solved my problem. Here is the last .cmd file I used for installation on each computer.

net stop AgentSupervision
sc delete AgentSupervision
pause
mkdir d:\atjob
copy Agent_Supervision.exe D:\atjob
copy sc.exe d:\atjob
d:
cd \atjob
sc create AgentSupervision start= auto binpath= D:\atjob\Agent_Supervision.exe
rem **  d:\atjob\Agent_Supervision.exe INSTALL
pause
sc start AgentSupervision
pause
sc query AgentSupervision
pause

May you take a look on my code ? I'm not sure that it's a good idea to declare objWMIService and tcpstart in main function ?

Thank's a lot. >_<

Edited by sksbir
Link to comment
Share on other sites

Hello sksbir.

As i said i've reworked on the service.au3 and the modification made by another member.

I will post the new script as soon as i've completed a better documentation (i'm a little bit lazy for that)

for your problem, seems that SCM request an hearbeat from the process, and no answer.

I'm not sure i've implemented all the function that SCM supports, but i know that his behavior is different

between Service Packs ( security ) and more between different systems.

My advice would be to totally debug the script, as i do for mines. Every lines outputed to a log file, then you can see where it hangs, if you can see.

So far we'll see where it hangs. I'm thinking about a DCOM issue, but not sure :/

-- 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]
Link to comment
Share on other sites

  • 3 weeks later...

Hello sksbir.

As i said i've reworked on the service.au3 and the modification made by another member.

I will post the new script as soon as i've completed a better documentation (i'm a little bit lazy for that)

for your problem, seems that SCM request an hearbeat from the process, and no answer.

I'm not sure i've implemented all the function that SCM supports, but i know that his behavior is different

between Service Packs ( security ) and more between different systems.

My advice would be to totally debug the script, as i do for mines. Every lines outputed to a log file, then you can see where it hangs, if you can see.

So far we'll see where it hangs. I'm thinking about a DCOM issue, but not sure :/

Can you please post the latest code even before the documentation is ready?

I am in a middle of work and wants to work on the latest one.

Thanks for sharing it... :D

Be Green Now or Never (BGNN)!

Link to comment
Share on other sites

  • 3 weeks later...

Will this service udf work with DOS .bat files? This works as is but not when I try to run it as a service.

Troubleshooting:

1. compiled exe

2. ran exe with -i option via the commandline

3. executed mservices.msc > found my service and started it.

$file_loc = @ScriptDir
$trigger = "trigger.txt"
$bat = "script.bat"

while 1
     $search = FileFindFirstFile($trigger)
     
     If $search == 1 Then

          Run($bat,$file_loc)
          FileDelete($file_loc & "\" & $trigger)

     EndIf

     Sleep(1000)

     FileClose($search)

WEnd

script.bat.txt

Link to comment
Share on other sites

  • 1 month later...

Hello arcker

you have made a really good job here....

You are amazing....

I have used your code to create a service , I am able to create/remove/start the process and in services.msc i can see the specified process is running. But in my _main() function contains one GUI screen. I am able to see the GUI screen when i login to the machine but it's hangs. There is no response when i click the tray icon.

I attached my code along with this .

Thanks & Regards

Ajomon

Edited by ajomon
Link to comment
Share on other sites

Hello arcker

you have made a really good job here....

You are amazing....

I have used your code to create a service , I am able to create/remove/start the process and in services.msc i can see the specified process is running. But in my _main() function contains one GUI screen. I am able to see the GUI screen when i login to the machine but it's hangs. There is no response when i click the tray icon.

I attached my code along with this .

Thanks & Regards

Ajomon

I could be wrong, but I believe graphical (GUI) processes can not be run as a service because it is not interactive with the desktop (Running as system user). You might be able to get it to work if you change the service to run as the user logged in.
Link to comment
Share on other sites

Win7 RTM Pro 32-bit

AutoIt 3.3.1.4 beta

I'm trying to get this script going, and it is working perfectly except for stopping the service. Every time I try to stop it from the services manager, I get

[SC] ControlService FAILED 1061:

The service cannot accept control messages at this time.

I'm using the changes suggested by udgeen in post #110.

I've tracked it down to the fact that the _Service_Ctrl() callback is never actually being called. Can anyone confirm or help?

Link to comment
Share on other sites

Updated Docs & Scripts.

Thx to Udgeen for best practice

and ShminkyBoy for modified, improved script

examples with GUI provided.

Please read the entire first post THEN ask the question.

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]
Link to comment
Share on other sites

Yep, same problem with new version (really nice by the way!!). For some reason the control handler callback is never being called. I've looked through the UDF and through MSDN and I can't find the problem. Hopefully someone else has some insight into this Win7 issue.

Link to comment
Share on other sites

Hi wraith

i've win7 in test to migrate from xp at work

this is the example that doesn't work ? i'm in x64 i'll test.

-- 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]
Link to comment
Share on other sites

With the new release there's a lot to edit/fix in the attached example (syntax changes and function name changes, etc), but yes, this example fails to properly stop the service. As I've found, the service control handler function is never called to process the STOP command. I can't figure out why.

Edited by wraithdu
Link to comment
Share on other sites

I've forgotten to thanx all of the contributors.

I'm thinking about spudw2k but there is a lot of other users.

I'll post updated examples asap, hoping they'll work on Win7.

-- 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]
Link to comment
Share on other sites

HI All ,

I need an urgent help,

I have created a service and within the service i am running another exe file which will display the GUI screen for data manipulation. But in the second process i have some registry read /write functions.Through the service if i am running the exe , it's not reading the registry values properly ,i am getting some values which is not related to the actual values.But when i am running the second exe interdependently it's reading and writing the things properly.

Can anyone please help .

Link to comment
Share on other sites

This is the problem running an app from a service...it is running in the wrong session (Session 0 in Vista/7) and as the wrong user (in the SYSTEM account). This means it has all the wrong environment and security token information to access user environment variables and user specific OS items such as HKCU. See my thread on elevating a process to the SYSTEM account for some possible solutions.

Here

Link to comment
Share on other sites

yep the process parent is your service, that runs under system proviliges by default.

The only solution is to elevate your privileges, as wraithdu done in his script.

this is the official MSDN method but i'm too lazy to refind the doc.

or the other is to run the process under your session, and communicate between the two processes by interprocess methods.

-- 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]
Link to comment
Share on other sites

I was looking into communicating with the service as well. But I ran into the same problem as when trying to stop the service in Win7. The control handler never gets the message, so any SERVICE_USER_DEFINED_CONTROL attempts fail :) Window messages don't work either. NamedPipes maybe? I saw those lurking in the AutoIt help file, but I haven't really played around with them yet. It seems hard to get them working in a non-blocking mode though.

Oh, here's the 2 CodeProject articles I was working from (scary titles, I know):

Link 1

Link 2

Edited by wraithdu
Link to comment
Share on other sites

This is the problem running an app from a service...it is running in the wrong session (Session 0 in Vista/7) and as the wrong user (in the SYSTEM account). This means it has all the wrong environment and security token information to access user environment variables and user specific OS items such as HKCU. See my thread on elevating a process to the SYSTEM account for some possible solutions.

Here

Hi wraithdu

Can u help me to implement the same in AUTOIT ?.

Thanks !!!

Ajomon

Link to comment
Share on other sites

@arcker

I have a Win7 working version of your Services UDF and example (works on XP still as well). I changed the handler function to use RegisterServiceCtrlHandlerExW() and a HandlerEx() callback. I've also converted the script to use all unicode function calls/params/structures + other little edits. PM me an email address and I can send it to you for testing, and you can decide if you want to post it.

Edited by wraithdu
Link to comment
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
 Share

×
×
  • Create New...