Jump to content

TCP server as a service


Recommended Posts

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

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

TCP chatrooms are user interactive.. and across the network

EDIT

and.... i dont know about the service modes ^_^ but just saying..

Edited by CodyBarrett
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

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...