# _Service_UDF v2 : Run your exe as Service

Service 1053

279 replies to this topic

### #1 arcker

arcker

Universalist

• Active Members
• 556 posts

Posted 10 September 2008 - 01:21 PM

Don't use this in production environment !

| _Services_UDF v2
|
| By Arcker
| Run your script as a service
|
|_______________________________________

|Updated on 02/03/2012
Best practices Updated 24/02/2012
Warning : 26/02/2012
New Version (v2 ) : 02/03/2012
|
Thx to ShminkyBoy, wraithdu, Udgeen and HolmesShelock for their great contributions.

Intro / History.

Hi,
Here is my _Service _ UDF
With this UDF, you can compile your autoit script and run it as service.

I've taken some functions already made by SumTimWong, seen here :
OpenScManager and I've added mines for running as service.

Any comments are welcome.

Previous download for both was over 5000, that leads me to make an update.

Hope you'll like it,

Regards, Arcker

History

Update : 02/03/2012

Ok there was some problems that I've tried to fix :
- Running was not exiting correctly since cleanup was executed without checking if the main loop is stopped
- Send Signal stopped was sometimes send error, whereas there were no errors
- Too much function, i've reset those in one main "ServiceMain" function, as MSDN says. Now there are some parts that should ne remove. Main
Code should be included after $bServiceRunning - Event has be stopped : too many$Running signal sent to SCM, and I've done that because the C++ example was done that way. Autoit cannot execute multiple thread so I've just remove those event, and when stop event is received, it just stops main loop.

Now the worst part :
In race condition, or not, the service doesn't stop well. I mean the main loop is break, but the process continues. So, as you can see, the service main is executed by SCM, not autoit directly, and I think that's the culprit. I'll try to post a request about this to autoit developers, but keep in mind that if it not autoit fault, or mine, so service will never be stable with autoit. Ive found a workaround by setting processclose at the end, it seems to work, but ... no problem with killing since your program is stopped, but then, i don't like this method.
edit : finally, i've added it and it seems to works well. But again, please report if you still encounter stop issue or something?

Now, see the updated example in page 1 to see the update. Respect the comments in code by not removing anything, and you service should run fine .... until stop

Todo :
I'll maybe add an option to execute a thread that just the service to be stopped. I've to do this in C++ then use trancexx udf, but maybe it's possible, and will improve stop service ability

11/01/2010 Updated with best practices

Features

- Transform your application by adding few functions to make it compatible with SCM
- Examples show you how to make GUIs and so on ( I won't be responsible for security reasons. A gui running as service will have system priviliges. ) No more a feature. Don't use it.
- Event coded : not cpu consuming. No more in v2 but cpu is still good.

Known Issues.

- Script sometimes crash when stopping. It should be fixed now but method used is not really ... clean. Please post if you encounter problems.

Howto.
• Compile an example
• Choose an appropriate location and copy the script here.
• open a command prompt, and execute the compiled script with option –I
• start / execute "services.msc" . You will see a service called "Autoit_service". you can execute "sc query" in a command prompt too.
• Launch it : it will run the previous compile script. The main function will be executed after the service_init.
• stop and relaunch the service as you wish.

Main UDF (v2 ) with Constants ( thread safe , careful with dllcall )

Note : 11/01/2010 Update by Wraithdu to work on Win7 ( Unicode optimised )
Note : 03/02/2012 Updated to v2, total rework. More stable. Should fix main crashes.

Examples / Session Change / v1 (lock, logon, etc) By HolmesShelock. Awesome work.
Edit : this example doesn't use v2 method

Example output to give you an idea
Plain Text
______________________________________
Log created: May 27, 2011 : 7:18:53 PM
______________________________________

May 27, 2011 : 7:18:53 PM [3144] >> Service started: Sessionchange
May 27, 2011 : 7:19:05 PM [3144] >> cbSize = 8 ,dwSessionId = 0

May 27, 2011 : 7:19:05 PM [3144] >> Session locked
May 27, 2011 : 7:19:12 PM [3144] >> cbSize = 8 ,dwSessionId = 0

May 27, 2011 : 7:19:12 PM [3144] >> Console session disconnected
May 27, 2011 : 7:19:12 PM [3144] >> cbSize = 8 ,dwSessionId = 0

May 27, 2011 : 7:19:12 PM [3144] >> Session unlocked
May 27, 2011 : 7:19:12 PM [3144] >> cbSize = 8 ,dwSessionId = 1

May 27, 2011 : 7:19:12 PM [3144] >> Console session connected
May 27, 2011 : 7:19:14 PM [3144] >> cbSize = 8 ,dwSessionId = 1

May 27, 2011 : 7:19:14 PM [3144] >> Session logged on
May 27, 2011 : 7:19:38 PM [3144] >> cbSize = 8 ,dwSessionId = 1

May 27, 2011 : 7:19:38 PM [3144] >> Session locked
May 27, 2011 : 7:19:40 PM [3144] >> cbSize = 8 ,dwSessionId = 1

May 27, 2011 : 7:19:40 PM [3144] >> Console session disconnected
May 27, 2011 : 7:19:41 PM [3144] >> cbSize = 8 ,dwSessionId = 0

May 27, 2011 : 7:19:41 PM [3144] >> Console session connected
May 27, 2011 : 7:19:41 PM [3144] >> cbSize = 8 ,dwSessionId = 1

Examples demos
Edit : No more supported in v2

Provide install parameters and so on

_Blank_v2.au3   2.71KB   3986 downloads by Spudw2k, optimised by myself to fit new code.

Note : only works on winxp, and no longer recommended. No support, and no question about it in this thread please.

Excellent example on how to make a GUI.

Synoptic

And for End Users, I've tried to explain the service control manager and the way it works with programs.

Best Practice, by arcker :

/!\ please read this if you encounter stability issues

I've to rework on services.au3 to reflect threadsafe.
Threadsafe means each dll call must be on "dllopened" instead of calling dll directly
for example, if you need a function in kernel32.dll, you have to open it and call it after.
That's contraignant since a lot of integrated functions in autoit are not programmed this way.
If you take my services.au3, at the end, you'll see reworked function to handle this change. I've not tried
services for a while, since i don't need it for now, but i can help you only if your provide whole script, to see how you call every functions.
I can tell that fix stability issues in callback, but i don't think it's need for your script, as far as you don't use callback.

Best Practice, by udgeen :

Good news! Probably i've found the working method of integrating service.au3 with other projects

I realised it after ASock.au3 project by Zatorg (please, sorry if im wrong) - ASock is asynck socket - tcp on event (uses ws2_32.dll).

Asock & sqlite didnt work together. The only reason for that was..._ArrayDisplay() func with gui!!! Ok. I made special sqlite.au3 without dependences. It works, but my udf seemed too be much heavy to use at another project.

Few weeks ago I returned to service.au3 and found TCP UDF, Event driven project based on ASock.au3. It seemed to work as example, but didn't work at all as service.

In my variant of service_example.au3 i posted msdn words about service_main procedure, that it must contain all global vars of project

I'll try to post that project as an another service_example.au3 in some weeks here. If it will works.

Some advice: use SysInternals Process Explorer (free gui based), or kill.exe from support tools to stop suspended service process. U can start-stop service even net start/net stop commands. Use file logging while debuging. No need to install-uninstall service after every recompilation: only stop, recompile, start. See, if it was suspended (while stopping) - kill process. The only reason not to stop service correctly i've found for today is unclean exit: opened sockets, maybe some dlls.
Edit : Arcker note: too bad, that would be too easy. unclean exit is not due to opened dll, but by some more internal exit checks or something.

FAQ.

Hey, I've got error 1063 or error 0, what does that mean ?

It simply means that you intend to run your script in scite or directly by executing it.

Your script has to be installed as service and run from it. Several ways to do it :
• U have to combine all Globals in one place: for example at the the begining. U have to make it with other udfs too... silly work
• Then sort Global Const and other Global statements. If u see something like global $x = 1 do that way: global$x leeve at top. $x =1 insert into module's (udf or project) Init func. • U have to do it even with standart udf... or use only necessary functions from it in your own include. Or... maybe u have another plan? • Try to build your project with modified udfs - does it works now? Hmm... But it have to Maybe later after everything will work fine i'll say "msdn is wrong, microsoft lies"... But maybe i'll say that microsoft - is not so bad, because autoit works in it • net start "yourservicename" • Services.msc • Use API provided _Service_start, Service_stop. I want to make a GUI ! First, you can't in Win7 and Win2008. That's a good thing since it was a security breach before ( a gui thats run under system account .... mmmm ) For winxp.That's your choice. You have to consider Udgeen best practice and my advice. Example by shminkyBoy provides a gui, but it's a proof of concept to prove that gui works. I REALLY DON'T RECOMMEND to make a gui SINCE it will be run as a Service with SYSTEM privileges The only GUIs I did was for install progression, without any interactivity. Ban all functions that include files management. I've to let the main function that way ? That's contraignant. Hey, a script intended to run as service is special no ? Autoit is not C++. The only way to have a "Main" in autoit is to have a function. If you find another way, please share it. #### Attached Files Edited by arcker, 02 March 2012 - 11:15 AM. • mcarmello likes this -- Arck System _ Soon --Ideas make everything"La critique est facile, l'art est difficile"Projects :Au3Service = Run your exe as service / Updated 27/05/2011 Get it Here ### #2 arcker arcker Universalist • Active Members • 556 posts Posted 10 September 2008 - 07:42 PM okkkkk one feature requested for so long time, and no comment at all.... maybe the title is not enough explicit.... -- Arck System _ Soon --Ideas make everything"La critique est facile, l'art est difficile"Projects :Au3Service = Run your exe as service / Updated 27/05/2011 Get it Here ### #3 spudw2k spudw2k i dunno what i'm doing • Active Members • 1,154 posts Posted 10 September 2008 - 07:59 PM Very nice arcker! Bout time this was done. Things I've Made: Projects: Cool Stuff: ### #4 WeMartiansAreFriendly WeMartiansAreFriendly Where's the kaboom? • Active Members • 1,245 posts Posted 10 September 2008 - 08:24 PM okkkkk one feature requested for so long time, and no comment at all.... maybe the title is not enough explicit.... Ahem.. "Silence is golden" Very nice arcker. Don't bother, It's inside your monitor!------GUISetOnEvent should behave more like HotKeySet() ### #5 Wooltown Wooltown Alpha Geek • Active Members • 478 posts Posted 11 September 2008 - 07:31 AM Wow, exactly what I have been looking for, GOOD JOB ! ### #6 arcker arcker Universalist • Active Members • 556 posts Posted 11 September 2008 - 07:47 AM @ Thx all I'm improving it to make it compatible with pause order and interrogate. Bout time this was done. What do you mean ? If you're talking about P-Trex method, using srvany, it's not a "standart" option. Mine is the same method as all of the C++ program and other language program. It was not possible before because callback was not implemented. Any suggestions / improvements are welcome. -- Arck System _ Soon --Ideas make everything"La critique est facile, l'art est difficile"Projects :Au3Service = Run your exe as service / Updated 27/05/2011 Get it Here ### #7 ChromeFan ChromeFan Universalist • Banned (NOT IN USE) • 280 posts Posted 11 September 2008 - 09:57 AM very good UDF and example! Website: www.cerescode.comForum: www.forum.cerescode.comIRC: irc.freenode.net , Channel: #Ceres--------------------Autoit Wrappers, Great additions to your script (Must See) (By: Valuater)Read It Befor Asking Question Click Here...--------------------Join Monoceres's Forums http://www.monoceres.se--------------------There are three kinds of people: Those who make things happen, those who watch things happen, and those who ask, What happened? Casey Stengel ### #8 StAbb StAbb Seeker • Active Members • 49 posts Posted 11 September 2008 - 04:29 PM Hey man great work! I was wondering what I should do though, I keep getting Error 0. When I try and run your example script or one of my own such as this: #include<Service.au3> _Service_Init("TestSerice") While 1 ConsoleWrite("Loop"&@CRLF) Sleep(100) WEnd ### #9 arcker arcker Universalist • Active Members • 556 posts Posted 11 September 2008 - 04:35 PM because you run it in debugger... so it is your autoit3.exe that runs. Tomkae your script work, compile it and create a service linked to it. my example integrates an install / uninstall option. -- Arck System _ Soon --Ideas make everything"La critique est facile, l'art est difficile"Projects :Au3Service = Run your exe as service / Updated 27/05/2011 Get it Here ### #10 StAbb StAbb Seeker • Active Members • 49 posts Posted 11 September 2008 - 04:58 PM I tried compiling the example script you provided above as well and sucsesfully installed the process. Should I now just re-exucaute the script without any params? Or is there something esle I should do before that. I also noticed the main() function was not run so I put it in after _Service_Init, and that is when I get error 0. Any ideas? I apologize for my inconvienience, I am new to the whole service idea. Plain Text #Region;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Version=Beta #AutoIt3Wrapper_Change2CUI=y #EndRegion;**** Directives created by AutoIt3Wrapper_GUI **** ; Example of using service UDF to make an exe possibly runeed as a service ; By Arcker ; 10/09/2008 #include<Service.au3>$sServiceName = "Autoit_Service"
If $cmdline[0] > 0 Then Switch$cmdline[1]
Case "install", "-i", "/i"
InstallService()
Case "remove", "-u", "/u", "uninstall"
RemoveService()
Case Else
ConsoleWrite(" - - - Help - - - " & @crlf)
ConsoleWrite(" Service Example params : " & @crlf)
ConsoleWrite("  -i : install service" & @crlf)
ConsoleWrite("  -u : remove service" & @crlf)
ConsoleWrite(" - - - - - - - - " & @crlf)
Exit
;start service.
EndSwitch
EndIf
_Service_init($sServiceName) main() Func main() While 1 ConsoleWrite("IN MAIN"&@CRLF) ;doing what you want here Sleep(1000) WEnd EndFunc ;==>main Func InstallService() ConsoleWrite("Installing service, please wait" & @CRLF) _Service_Create("",$sServiceName, "Autoit Service Test", @ScriptFullPath)
If @error Then
ConsoleWrite("Problem installing service, Error number is " & @error & @CRLF & " message  : " & _WinAPI_GetLastErrorMessage())
Else
ConsoleWrite("Installation of service successful")
EndIf
Exit
EndFunc  ;==>InstallService
Func RemoveService()
_StopService("", $sServiceName) _DeleteService("",$sServiceName)
if not @error then ConsoleWrite("service removed successfully" & @crlf)
Exit
EndFunc  ;==>RemoveService

### #11 spudw2k

spudw2k

i dunno what i'm doing

• Active Members
• 1,154 posts

Posted 11 September 2008 - 05:20 PM

I get error 1063 with a compiled script.

Projects:

Cool Stuff:

### #12 trancexx

trancexx

Hm, I really shouldn't.

• Active Members
• 5,242 posts

Posted 11 September 2008 - 06:23 PM

I get error 1063 with a compiled script.

That is expected, just drop it on command prompt and add -i or whatever

eMyvnE

### #13 arcker

arcker

Universalist

• Active Members
• 556 posts

Posted 11 September 2008 - 07:01 PM

ok i'll try to reexplain.

the example script contains a sort of autoinstall / uninstall.
Please dinstinguish it from the whole service processus.

1 - Compile the example
2 - Choose an appropriate location and copy the script here.
3 - open a command prompt, and execute the compiled script with option -i
4 - start / execute "services.msc" . You will see a service called "Autoit_service". you can execute "sc query" in a command prompt too.
5 - Launch it : it will run the previous compile script. The main function will be executed after the service_init.
6 - stop and relaunch the service as you wish.

Error 1063 : follow this procedure. Don't run it from scite
Error 0 : same
-- Arck System _ Soon --Ideas make everything"La critique est facile, l'art est difficile"Projects :Au3Service = Run your exe as service / Updated 27/05/2011 Get it Here

### #14 spudw2k

spudw2k

i dunno what i'm doing

• Active Members
• 1,154 posts

Posted 11 September 2008 - 08:01 PM

I still experience error 1063. even though it is compiled and installed. If I run it directly it errors. If I start it from the SCM it starts but I do not get the expected results.

Projects:

Cool Stuff:

### #15 Micha1405

Micha1405

• Active Members
• 107 posts

Posted 11 September 2008 - 08:22 PM

for me it works !!

you have to open a command prompt and type "Service_Example.exe /i"

type: SC QUERY

you get the result:

SERVICE_NAME: Autoit_Service
DISPLAY_NAME: Autoit Service Test
TYPE : 10
STATE : 4 R
(
WIN32_EXIT_CODE : 0 (
SERVICE_EXIT_CODE : 0 (
CHECKPOINT : 0x0
WAIT_HINT : 0x0

### #16 Micha1405

Micha1405

• Active Members
• 107 posts

Posted 11 September 2008 - 08:27 PM

for me it works !!

be sure you have administrator privileges !!!!!!!!!!!!!!!!!
you have to open a command prompt and type "Service_Example.exe /i"

type: SC QUERY

you get the result:

SERVICE_NAME: Autoit_Service
DISPLAY_NAME: Autoit Service Test
TYPE : 10
STATE : 4 R
(
WIN32_EXIT_CODE : 0 (
SERVICE_EXIT_CODE : 0 (
CHECKPOINT : 0x0
WAIT_HINT : 0x0

@Arcker greate stuff, well done

Edited by Micha1405, 11 September 2008 - 08:37 PM.

### #17 spudw2k

spudw2k

i dunno what i'm doing

• Active Members
• 1,154 posts

Posted 11 September 2008 - 08:36 PM

So from what I can tell, the service starts fine, but my main function never runs. my main func consists of a filewrite to c:\text.txt and a 10 second sleep.

Inside a while loop of course

Edited by spudw2k, 11 September 2008 - 08:37 PM.

Projects:

Cool Stuff:

### #18 arcker

arcker

Universalist

• Active Members
• 556 posts

Posted 11 September 2008 - 10:04 PM

remember that the service runs under system account privileges.
i didn't test some function in the while loop because it's seems logical that it loop here.
plz post the code here. i'll take a look. I don't pretend that there is no bug
-- Arck System _ Soon --Ideas make everything"La critique est facile, l'art est difficile"Projects :Au3Service = Run your exe as service / Updated 27/05/2011 Get it Here

### #19 spudw2k

spudw2k

i dunno what i'm doing

• Active Members
• 1,154 posts

Posted 11 September 2008 - 10:40 PM

remember that the service runs under system account privileges.
i didn't test some function in the while loop because it's seems logical that it loop here.
plz post the code here. i'll take a look. I don't pretend that there is no bug

I appreciate any support you can give. Great job so far.

AutoIt
#NoTrayIcon
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Version=Beta
#AutoIt3Wrapper_Change2CUI=y
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
; Example of using service UDF to make an exe possibly runeed as a service
; By Arcker
; 10/09/2008
#include<Service.au3>
$sServiceName = "Autoit_Service" If$cmdline[0] > 0 Then
Switch $cmdline[1] Case "install", "-i", "/i" InstallService() Case "remove", "-u", "/u", "uninstall" RemoveService() Case Else ConsoleWrite(" - - - Help - - - " & @crlf) ConsoleWrite(" Service Example params : " & @crlf) ConsoleWrite(" -i : install service" & @crlf) ConsoleWrite(" -u : remove service" & @crlf) ConsoleWrite(" - - - - - - - - " & @crlf) Exit ;start service. EndSwitch EndIf _Service_init($sServiceName)

Func main()
While 1
;doing what you want here
fileWrite("C:\test.txt",@ComputerName & @TAB & @ScriptName & @CRLF)
Sleep(10000)
WEnd
EndFunc   ;==>main
Func InstallService()
ConsoleWrite("Installing service, please wait" & @CRLF)
_Service_Create("", $sServiceName, "Autoit Service Test", @ScriptFullPath) If @error Then ConsoleWrite("Problem installing service, Error number is " & @error & @CRLF & " message : " & _WinAPI_GetLastErrorMessage()) Else ConsoleWrite("Installation of service successful") EndIf Exit EndFunc ;==>InstallService Func RemoveService() _StopService("",$sServiceName)
_DeleteService("", \$sServiceName)
if not @error then ConsoleWrite("service removed successfully" & @crlf)
Exit
EndFunc   ;==>RemoveService

Edited by spudw2k, 11 September 2008 - 10:41 PM.

Projects:

Cool Stuff:

### #20 trancexx

trancexx

Hm, I really shouldn't.

• Active Members
• 5,242 posts

Posted 11 September 2008 - 11:01 PM

So, when is that function 'main()' called?

eMyvnE

### Also tagged with one or more of these keywords: Service, 1053

#### 1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users