Jump to content
Sign in to follow this  
arcker

_Service_UDF v4 : Build your own service with autoit code

Recommended Posts

Its almost working perfectly for me for my custom AutoIt program "Reboot Manager". Thanks arcker! just 2 things...

  • Although the service type is "automatic", it does not start automatically. Once I click start (or use sc) it starts and runs fine.
  • I need to set the service to interact with the desktop.
---- later ----

From the sc help, I figured out the problem with interact...

The service can interact with the desktop, receiving input from users. Interactive services must be run under the LocalSystem account. This type must be used in conjunction with type= own or type= shared (for example, type= interact type= own). Using type= interact by itself will generate an invalid parameter error.

So I had to use BitAnd (110). However, I am still mystified why my Autostart service is not autostarting.

Edited by donald2

--Donald

Share this post


Link to post
Share on other sites

[*]Although the service type is "automatic", it does not start automatically. Once I click start (or use sc) it starts and runs fine.

You may already know this, but did you restart the computer to see if the service starts? When a service is installed it is not automatically started at the time of installation. Edited by spudw2k

Share this post


Link to post
Share on other sites

Thanks for the great help guys, sorry if I'm being a pain :)

I will try these different methods that you guys have suggested and get back to you all.

Thanks again,

Steve

Edited by StAbb

Share this post


Link to post
Share on other sites

You may already know this, but did you restart the computer to see if the service starts? When a service is installed it is not automatically started at the time of installation.

Yes, I know. For whatever reason it didn't start at reboot the first time. However, now it is. BUT... I have another problem...

I verified that "Allow service to interact with desktop" is checked, but even though the service is running, the SystemTray icon with its TraySetToolTip text are not appearing. hmmm

Edited by donald2

--Donald

Share this post


Link to post
Share on other sites

I'm not sure that process under system account can access to systray.

i would say not. That's why software like antivirus need a "gui" that start only under logon session.


-- 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

I'm not sure that process under system account can access to systray.

i would say not. That's why software like antivirus need a "gui" that start only under logon session.

Thanks, arcker. That makes sense. Except that when I use the services.msc to start it configured to run under the LocalSystem account and to interact with the desktop, I ***do*** see the systemtray icon. I am running XP SP3.

FWIW, even if I set the service to use a local admin account, the SystemTray icon does not appear even after a reboot.

Edited by donald2

--Donald

Share this post


Link to post
Share on other sites

let me understand well :

you want the icon appeared as fas as the service started before the systray ? that's impossible.

but you see the icon when you run it manually ? it makes sense, because systray is loaded when yo do so .... no ?


-- 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

let me understand well :

you want the icon appeared as fas as the service started before the systray ? that's impossible.

but you see the icon when you run it manually ? it makes sense, because systray is loaded when yo do so .... no ?

I was able to amke it work the way I wanted, viz.

  • Service starts up and run fine when no user is logged in.
  • GUI stuff (System Tray icon & message, and various dialogs) appear when the user is logged in.
I was able to do this by using conditional statements like

If WinExists("Program Manager") = 1 Then
  GUI stuff here
EndIf

--Donald

Share this post


Link to post
Share on other sites

I compiled the example, un-commented the msgbox line in the main() function to see if it works when I install it and start it.

So I install the service, I see that it is installed by checking services.msc and then I start it and I get an Error 0 still :)

Any ideas?

Thanks,

Steve

Share this post


Link to post
Share on other sites

start it from your services.msc, not from commandline.


-- 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

I was able to amke it work the way I wanted, viz.

  • Service starts up and run fine when no user is logged in.
  • GUI stuff (System Tray icon & message, and various dialogs) appear when the user is logged in.
I was able to do this by using conditional statements like

If WinExists("Program Manager") = 1 Then
  GUI stuff here
EndIf
not bad, but if the service has guy when you are not logged in, the guis will show directly when you have logged in.

no need to recall a winstate or something. They are just hidden until the explorer.exe is launched

so i wonder if it's necessary to do so.


-- 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

not bad, but if the service has guy when you are not logged in, the guis will show directly when you have logged in.

no need to recall a winstate or something. They are just hidden until the explorer.exe is launched

so i wonder if it's necessary to do so.

Somehow putting in that code did make it possible for the service to start without some one logged in, whereas before it would not. However, I did find that the WinExists("Program Manager") code needs to be before _Service_init() otherwise the script hangs.

What I am actually finding is that if the service starts before the user is logged on, there is no icon (and Tray Tool Tip -- which I really want) unless I stop and restart the service. I've tried all kinds of code in the service itself and nothing works. What I finally decided to do was to write a very simple AutoIt3 script to stop and start my service and put that in the HKLM Run.

I was originally launching the program using the registry Run line, but I need it to continue running after the user is logged out. The program reboots the PC after the uptime limit is reached. This is the info displayed in the Tool Tip.

Edited by donald2

--Donald

Share this post


Link to post
Share on other sites

I do have a new problem now, though, Arcker. When my program is running as a service, my code can not access the commandline parameters (set in the service configuration) by the $CmdLine[0 to i] variable. Any suggestions?


--Donald

Share this post


Link to post
Share on other sites

start it from your services.msc, not from commandline.

I do! I start it manually in the services.msc manager : (

Any ideas?

Share this post


Link to post
Share on other sites

nope.

plz guys post your code.

I don't have problem since i use a service to install a program silently, but i'm not using cmdline[x]

strange thing.


-- 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

nope.

plz guys post your code.

I don't have problem since i use a service to install a program silently, but i'm not using cmdline[x]

strange thing.

Here is my code, arcker. I would really appreciate any feedback on how to access service commandline parameters. (It seems that $CmdLine does not work for service start parameters .)

#Region;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Version=Beta
#AutoIt3Wrapper_Change2CUI=y
#AutoIt3Wrapper_icon=shellarrownup_32.ico
#AutoIt3Wrapper_AU3Check_Stop_OnWarning=y
#EndRegion;**** Directives created by AutoIt3Wrapper_GUI ****
; From example of using service UDF to make an exe possibly run as a service
; By Arcker
; 10/09/2008
#include <Date.au3>
#include<Service.au3>
$wbemFlagReturnImmediately = 0x10
$wbemFlagForwardOnly = 0x20
$colItems = ""
$sServiceName = "Reboot Manager"
If $cmdline[0] > 0 Then
    Switch $cmdline[1]
        Case "install", "-i", "/i"
            InstallService()
        Case "remove", "-u", "/u", "uninstall"
            RemoveService()
        Case "/?"
            ConsoleWrite(" - - - Help - - - " & @crlf)
            ConsoleWrite(" Service params : " & @crlf)
            ConsoleWrite("  -i : install service" & @crlf)
            ConsoleWrite("  -u : remove service" & @crlf)
            ConsoleWrite(" - - - - - - - - " & @crlf)
            ConsoleWrite(" Switches: " & @crlf)
            ConsoleWrite("  /UL=10 Uptime Limit in days" & @crlf)
            ConsoleWrite("  /NI=60 Notification Interval in minutes" & @crlf)
            ConsoleWrite("  /ND=300 Notification message Duration in seconds" & @crlf)
            ConsoleWrite("  /EP=00:00 Earliest Possible random reboot in HH:MM" & @crlf)
            ConsoleWrite("  /LP=03:00 Latest Possible random reboot in HH:MM" & @crlf)
            ConsoleWrite("  /WT=5 Warning Time before reboot in minutes" & @crlf)
            Exit
      ;start service.
    EndSwitch
EndIf

_Service_init($sServiceName)
Opt ("TrayAutoPause", 0)
Opt ("TrayMenuMode", 1)


main()

Func main()
    $UL = 10
    $NI = 60
    $ND = 300
    $EP = "00:00"
    $LP = "03:00"
    $WT = 5
;   MsgBox(0,"CmdLine Count", $CmdLine[0])
    For $i = 1 to $CmdLine[0]
      $varname = StringMid($CmdLine[$i],2,2)
      $value = StringMid($CmdLine[$i],5)
      Assign($varname,$value)
      Switch $varname
        Case "UL"
          $UL = Eval("UL")
        Case "NI"
          $NI = Eval("NI")
        Case "ND"
          $ND = Eval("ND")
        Case "EP"
          $EP = Eval("EP")
        Case "LP"
          $LP = Eval("LP")
        Case "WT"
          $WT = Eval("WT")
      EndSwitch
;     MsgBox(0,"Commandline", "$Varname: " & $varname & @LF & "$Value: " & Eval($varname))
    Next
    $EP = $EP & ":00"
    $LP = $LP & ":00"
    $Today = @Year & "/" & @Mon & "/" & @MDay
  ;Determine Reboot Window Length in minutes
    $RWL = _DateDiff('n',$Today & " " & $EP,$Today & " " & $LP)
  ;MsgBox(0,"Reboot Window Length", $RWL & " minutes")
  ;Determine Random Reboot Time
    $RRTraw = _DateAdd('n', Random(0,$RWL,1), $Today & " " & $EP)
    Dim $RRTarray
    _DateTimeSplit($RRTraw,$Today,$RRTarray)
    For $i = 1 to 3
      If StringLen($RRTarray[$i]) = 1 Then
        $RRTarray[$i] = "0" & $RRTarray[$i]
      EndIf
    Next
    $RRT = $RRTarray[1] & ":" & $RRTarray[2] & ":" & $RRTarray[3]
  ;MsgBox(0,"Random Reboot Time", $RRT)

  ;Determine Warning Message Time
    $WMTraw = _DateAdd('n', -$WT, $RRTraw)
    Dim $WMTarray
    _DateTimeSplit($WMTraw,$Today,$WMTarray)
    For $i = 1 to 3
      If StringLen($WMTarray[$i]) = 1 Then
        $WMTarray[$i] = "0" & $WMTarray[$i]
      EndIf
    Next
    $WMT = $WMTarray[1] & ":" & $WMTarray[2] & ":" & $WMTarray[3]
  ;MsgBox(0,"Random Reboot Time", $RRT & @LF & "Warning: " & $WMT)

  ;Determine Last Bootup Time
    $objWMIService = ObjGet("winmgmts:root\CIMV2")
    $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_OperatingSystem", "WQL", $wbemFlagReturnImmediately + $wbemFlagForwardOnly)
    If IsObj($colItems) Then
       For $objItem In $colItems
          $LBT = StringStripWS($objItem.LastBootUpTime,8)
       Next
    Endif
    $sLBT = StringLeft($LBT,4) & "/" & StringMid($LBT,5,2) & "/" & StringMid($LBT,7,2) & " " & StringMid($LBT,9,2) & ":" & StringMid($LBT, 11,2) & ":" & StringMid($LBT,13,2)

    $NNT = _NowCalc()
    $Warned = False
    $Notified = False
    While 1
        Opt ("TrayAutoPause", 0)
        Opt ("TrayMenuMode", 1)
        $DaysUp = _DateDiff('d', $sLBT, _NowCalc())
      ;MsgBox(0,"DaysUp",$DaysUp)
        $RebootRequirementText = "This PC has been up for " & $DaysUp & " days. " & _
                "To maintain system security, stability, and performance, PC reboots are required every " & _
                $UL & " days."
      ;MsgBox(0,"Last Bootup Time", $LBT & @LF & $sLBT & @LF & "Days up: " & $DaysUp & @LF & $RebootRequirementText, 10)
        $Today = @Year & "/" & @Mon & "/" & @MDay
        If _DateDiff('s', $Today & " " & $WMT, _NowCalc()) > 0 _
            And _DateDiff('s', $Today & " " & $LP, _NowCalc()) < 0 Then
          $WarnNow = True
        Else
          $WarnNow = False
        EndIf
        If _DateDiff('s', $NNT, _NowCalc()) > 0 Then
          $NotifyAgain = True
        Else
          $NotifyAgain = False
        EndIf
        If _DateDiff('s', $Today & " " & $RRT, _NowCalc()) >= 0 _
            And _DateDiff('s', $Today & " " & $LP, _NowCalc()) <= 0 Then
          $RebootNow = True
        Else
          $RebootNow = False
        EndIf
        $TipText = "Uptime: " & $DaysUp & " days" & @LF & "Limit: " & $UL & " days"
        If $DaysUp >= $UL Then
          $TipText = $TipText & @LF & "Rebooting at " & StringLeft($RRT,5)
          Select
            Case $Notified = False or $NotifyAgain = True
              $NNT = _DateAdd('n', $NI, _NowCalc())
              MsgBox(0,"Scheduled Reboot Notification", $RebootRequirementText & @LF & @LF & "System reboot is scheduled for " & StringLeft($RRT,5), $ND)
              $Notified = True
            Case $WarnNow = True And $Warned = False
              MsgBox(0,"This PC will restart at " & StringLeft($RRT,5), $RebootRequirementText & @LF & @LF & "You have " & $WT & " minutes to save your work before this PC restarts.", $WT * 59)
              $Warned = True
            Case $RebootNow = True
              Shutdown(6)
          EndSelect
        EndIf
        TraySetToolTip ($TipText)
        Sleep(1000)
    WEnd
EndFunc;==>main
Func InstallService()
    ConsoleWrite("Installing service, please wait..." & @CRLF)
    _Service_Create("", $sServiceName, $sServiceName, @ScriptFullPath, "LocalSystem", "", 0x00000110)
    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 donald2

--Donald

Share this post


Link to post
Share on other sites

I'm not sure if the SCM supports commandline params.

I tried appending a commandline param to my test service binpath but it fails to start.

sc config "AutoIt_Service_Test" binpath= "\"c:\Documents and Settings\profile\Desktop\testsvc.exe\" -s"

fails to start

sc config "AutoIt_Service_Test" binpath= "c:\Documents and Settings\profile\Desktop\testsvc.exe"

reset and works fine

Edited by spudw2k

Share this post


Link to post
Share on other sites

scm supports parameters.

but autoit maybe don't handle when launched by scm

look all of the services that uses svchost.exe

example :

Audio Windows.


-- 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

I'm not sure if the SCM supports commandline params.

I tried appending a commandline param to my test service binpath but it fails to start.

sc config "AutoIt_Service_Test" binpath= "\"c:\Documents and Settings\profile\Desktop\testsvc.exe\" -s"

fails to start

sc config "AutoIt_Service_Test" binpath= "c:\Documents and Settings\profile\Desktop\testsvc.exe"

reset and works fine

For now I am editing the HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Reboot Manager\ImagePath value to add my switches as needed. It works.

--Donald

Share this post


Link to post
Share on other sites

So it does. :) I had a thought that maybe spaces in the path would be the prob, but still get the result even when run from a path with no spaces in it.

Edited by spudw2k

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...