Sliver Posted April 15, 2009 Share Posted April 15, 2009 (edited) I'm wondering if anyone has any experience with running a compiled script that's a TCP listener as a service. I have created a listener app that waits for a connection from a remote machine and then when it receives the command it downloads and installs needed windows updates. Everything works great if I run it locally, but I'm trying to get it to run as a service. I used the Service.au3 UDF to create the service and the service starts, but it doesn't seem to be actually running the script because the TCP port is not open. The listener code is below. Any help would be greatly appreciated. CODE#Include <Array.au3> #Include <misc.au3> #Include <File.au3> #Include <Service.au3> Global $MainSocket = -1 Global $ConnectedSocket = -1 Global $colNeeded, $arrNeeded, $host Local $MaxConnection = 1; Maximum Amount Of Concurrent Connections Local $MaxLength = 512; Maximum Length Of String Local $Port = 1000; Port Number Local $ServerIP = @IPAddress1; Server IpAddress Local $host = @ComputerName Local $sServiceName = "wulistener" If $cmdline[0] > 0 Then Switch $cmdline[1] Case "install", "-i", "/i" InstallService() Case "remove", "-u", "/u", "uninstall" RemoveService() Case Else ;start services. EndSwitch EndIf _Service_init($sServiceName) TCPStartup() $MainSocket = TCPListen($ServerIP, $Port) If $MainSocket = -1 Then _FileWriteLog(@ScriptDir & "\event.log","Could not start TCP") Exit EndIf Func main() While 1 Sleep(10) $ConnectedSocket = TCPAccept($MainSocket) If $ConnectedSocket <> -1 Then ; Someone Connected TrayTip ( "", "Connected", 3) _FileWriteLog(@ScriptDir & "\event.log","Connection Established") Do Sleep(100) $Data = TCPRecv($ConnectedSocket, $MaxLength) Until $Data <> "" Switch $Data Case "~bye" TrayTip("Session Ended","Connection Terminated",3) _Exit() Case "u" _FindNeededUpdates($host) _Exit() Case Else EndSwitch EndIf WEnd EndFunc ;- FUNCTIONS - Func _CreateMSUpdateSession($strHost = $host) $objSession = ObjCreate("Microsoft.Update.Session",$strHost) If Not IsObj($objSession) Then Return 0 Return $objSession EndFunc Func _CreateSearcher($objSession) If Not IsObj($objSession) Then Return -1 Return $objSession.CreateUpdateSearcher EndFunc Func _GetNeededUpdates($objSearcher) If Not IsObj($objSearcher) Then Return -5 $colNeeded = $objSearcher.Search("IsInstalled=0 and Type='Software'") Return $colNeeded EndFunc Func _FindNeededUpdates($host) ;~ SplashTextOn("Please Wait.","Finding Needed Updates",200,30,-1,-1,32) $arrNeeded = _FetchNeededData($host) ;~ SplashOff() TrayTip ("","Checking for updates",3) _FileWriteLog(@ScriptDir & "\event.log","Checking for updates") If IsArray($arrNeeded) and $arrNeeded[0][0]<>"" Then ;~ _ArrayDisplay($arrNeeded) _UpdatesDownloadandInstall() Else ;~ MsgBox(0,"No Needed Updates Found","No Needed Updates Found",3) TrayTip ("","No updates needed",3) _FileWriteLog(@ScriptDir & "\event.log","No updates needed") ;~ TCPSend($ConnectedSocket, "none") EndIf $objSearcher = 0 $arrNeeded = 0 EndFunc Func _FetchNeededData($host) $objSearcher = _CreateSearcher(_CreateMSUpdateSession($host)) $colNeeded = _GetNeededUpdates($objSearcher) $objSearcher = 0 Dim $arrNeeded[1][2] For $i = 0 To $colNeeded.Updates.Count-1 If $i < $colNeeded.Updates.Count-1 Then ReDim $arrNeeded[$i+2][2] $update = $colNeeded.Updates.Item($i) $arrNeeded[$i][0] = $update.Title $arrNeeded[$i][1] = $update.Description Next If Not IsArray($arrNeeded) Then msgbox(16,"Failed to Fetch Needed Updates " & $host,"",5) Return 0 EndIf Return $arrNeeded EndFunc Func _UpdatesDownloadandInstall() TrayTip ("","Downloading updates",3) $objSearcher = _CreateMSUpdateSession($host) For $x = 0 to UBound($arrNeeded) -1 $item = ($arrNeeded[$x][0]) For $i = 0 To $colNeeded.Updates.Count-1 $update = $colNeeded.Updates.Item($i) If $item = $update.Title Then $updatesToDownload = ObjCreate("Microsoft.Update.UpdateColl") $updatesToDownload.Add ($update) $DownloadSession = $objSearcher.CreateUpdateDownloader() $DownloadSession.Updates = $updatesToDownload $DownloadSession.Download EndIf Next Next $reboot= 0 TrayTip ("","Installing updates",3) For $x = 0 To UBound($arrNeeded) -1 $item = ($arrNeeded[$x][0]) For $i = 0 To $colNeeded.Updates.Count-1 $update = $colNeeded.Updates.Item($i) If $item = $update.Title And $update.IsDownloaded Then _FileWriteLog(@ScriptDir & "\event.log","Installing update: " & $item) $InstallSession = $objSearcher.CreateUpdateInstaller() $updatesToInstall = ObjCreate("Microsoft.Update.UpdateColl") $updatesToInstall.Add($update) $InstallSession.Updates = $updatesToInstall $installresult = $InstallSession.Install If $installresult.RebootRequired Then $reboot = 1 EndIf Next Next If $reboot Then TrayTip ("Updated","A reboot is required",3) ;~ Msgbox(0,"Installation Complete","A Reboot is Required.") ;~ TCPSend($ConnectedSocket, "Rebooting") ;~ Shutdown(6); Force reboot EndIf $DownloadSession = 0 $updatesToDownload = 0 Return 0 EndFunc Func InstallService() ConsoleWrite("Installing service, please wait" & @CRLF) _Service_Create("", $sServiceName, "AutoIt_WUListener", '"' & @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 Func _Exit() If $ConnectedSocket <> - 1 Then TCPCloseSocket($ConnectedSocket) $ConnectedSocket = -1 EndIf EndFunc Func OnAutoItExit() If $ConnectedSocket <> - 1 Then TCPSend($ConnectedSocket, "~bye") TCPCloseSocket($ConnectedSocket) EndIf If $MainSocket <> -1 Then TCPCloseSocket($MainSocket) TCPShutdown() EndFunc;==>OnAutoItExit Edited April 15, 2009 by Sliver Link to comment Share on other sites More sharing options...
dexto Posted April 15, 2009 Share Posted April 15, 2009 (edited) Services in Windows are tricky... as far as i know there are two modes for service app. one is interactive where application can interact where it han have GUI and interact with user directly and other is network mode where it can access network. If one mode is set it can't use the other. So effectively if you have interactive mode for service it can't work with internet. I'm not shue what UDF is setting it to but you can check by viewing the properties of the service in computer management. Edited April 15, 2009 by dexto Link to comment Share on other sites More sharing options...
CodyBarrett Posted April 15, 2009 Share Posted April 15, 2009 (edited) TCP chatrooms are user interactive.. and across the network EDIT and.... i dont know about the service modes but just saying.. Edited April 15, 2009 by CodyBarrett [size="1"][font="Tahoma"][COMPLETED]-----[FAILED]-----[ONGOING]VolumeControl|Binary Converter|CPU Usage| Mouse Wrap |WinHide|Word Scrammbler|LOCKER|SCREEN FREEZE|Decisions Decisions|Version UDF|Recast Desktop Mask|TCP Multiclient EXAMPLE|BTCP|LANCR|UDP serverless|AIOCR|OECR|Recast Messenger|AU3C|Tik-Tak-Toe|Snakes & Ladders|BattleShips|TRON|SNAKE_____________________[u]I love the Helpfile it is my best friend.[/u][/font][/size] Link to comment Share on other sites More sharing options...
dexto Posted April 15, 2009 Share Posted April 15, 2009 @CodyBarrett and..? Can you elaborate on how is that contradicting the fact of the service modes? Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now