Used single-quote instead of semi-colon as comment character.

#pragma compile(Console, true)
; Change this to 'false' to build a 32-bit binary
#pragma compile(x64, true)
#pragma compile(UPX, true)
; The name of the binary to generate
#pragma compile(Out, cloudconfig.exe)
; The icon to use as the progrma icon (gets jammed into binary)
#pragma compile(Icon, Bogo-D-Project-Disk-iDisk.ico)
; Icon courtesy http://bogo-d.deviantart.com
; Ownership info
#pragma compile(CompanyName, 'Dimension Data')
#pragma compile(FileDescription, 'Cloud Config Service')
#pragma compile(Comments, 'Cloud Config Service')
#pragma compile(FileVersion, 1.3.1.2)
#pragma compile(InternalName, 'CloudConfig')
#pragma compile(LegalCopyright, 'Copyright 2015 Dimension Data')

; We don't need no stinkin' trayicon!
#NoTrayIcon
; Since we will be modifying the system, we need Admin
#RequireAdmin

; Our logging routines
#include "Log.au3"
#include "Misc.au3"
; Routines for interfacing with Service Manager
#include "Services.au3"
#include "StringConstants.au3"
#include <FileConstants.au3>
#include <EventLog.au3>

; Our constants and variables
; The service name(s)
Global Const $sServiceName = "CloudConfig"
Global Const $sServiceDisplayName = "CloudConfig"
; The directory we expect to find our config file and other sundries
Global Const $prepDir = 'C:\CloudConfigService'
; The config file for the service
Global Const $configFile = $prepDir & '\CloudConfig.ini'
; We extract the command from the config file and jam it in this variable
Global $command = ''
; This is the number of boots the system has performed (as extracted from
; the config file)
Global $rebootcount = 0

; constants for Event log
Global Const $WE_SUCCESS = 0
Global Const $WE_ERROR = 1
Global Const $WE_WARNING = 2
Global Const $WE_INFORMATION = 4
Global Const $WE_SUCCESSAUDIT = 8
Global Const $WE_FAILUREAUDIT = 16

; The CCS_BOOT_COUNT is used to determine when to fire off the customization
; For Priced Software images on the Dimension Data Cloud, the value needs to be
; 2. For 3rd parties making images that can be imported into the Cloud, the value
; needs to be 3 to account for the extra boot that occurs when the image is initially
; imported into the platform.
;
; Uncomment to build for a Priced Software image
;Global Const $CCS_BOOT_COUNT = 2
; Uncomment to build a 3rd party image
Global Const $CCS_BOOT_COUNT = 3

; for future feature expansion, not currently used
Global $pingHost = '256.0.0.1' ; yes, it's an illegal IP. this is by design
Global $sleepyTime = 5000 ; Ping timeout, in milliseconds
Global $oldHostname = ''

If Not @Compiled Then Exit
If Not _Singleton(@ScriptName, 1) Then
   If $cmdline[0] > 0 Then
	  If $cmdline[1] = "finish" Then
		 WriteLog("Removing service.")
		 RemoveService()
	  Else
		 WriteLog("Unrecognized command. Terminating due to multiple instances.")
	  EndIf
	  Exit
   EndIf
   WriteLog("Multiple instances running. Terminating.")
   Exit
EndIf

If $cmdline[0] > 0 Then
	Switch $cmdline[1]
		Case "install", "-i", "/i"
			InstallService()
		Case "remove", "-u", "/u", "uninstall"
			RemoveService()
		Case "run", "-r", "/r", "start"
			_SelfRun($sServiceName, "start")
		Case "stop", "-s", "/s"
			_SelfRun($sServiceName, "stop")
		Case Else
			;WriteLog(" - - - Help - - - " & @crlf)
			;WriteLog(" Service Example Params : " & @crlf)
			;WriteLog("  -i : Installs service" & @crlf)
			;WriteLog("  -u : Removes service" & @crlf)
			;WriteLog("  -r : Runs the service" & @crlf)
			;WriteLog("  -s : Stops the service" & @crlf)
			;WriteLog(" - - - - - - - - " & @crlf)
			Exit
	EndSwitch
Else
	If Not _Service_Exists($sServiceName) Then
		If MsgBox(20, "Service Not Installed.", "Would you like to install this service?" & @CRLF & $sServiceName) = 6 Then
			If InstallService() Then
				If MsgBox(4, $sServiceName, "Service Installed Successfully." & @CRLF & "Do you wish to start the process?") = 6 Then _SelfRun($sServiceName, "start")
			EndIf
		Else
			Exit
		EndIf
	EndIf
EndIf

_Service_Init($sServiceName)
Exit

Func _main($iArg, $sArgs)

   Local $hostNameChanged = False

   If Not _Service_ReportStatus($SERVICE_RUNNING, $NO_ERROR, 0) Then
	  WriteLog("Error sending running status, exiting")
	  _Service_ReportStatus($SERVICE_STOPPED, _WinAPI_GetLastError(), 0)
	Exit
   EndIf

   If Not FileExists($configFile) Then
	  ; if we don't have our config file, we abort all operations
	  WriteLog('No config file present. Aborting.')
	  WriteEventLog($WE_ERROR, 'No config file present.')
	  _Service_ReportStatus($SERVICE_STOPPED, _WinAPI_GetLastError(), 0)
	Exit
   EndIf

   Local $bServiceRunning = True ; REQUIRED

   ; how many reboots have we performed?
   Local $rebootcount = readConfig('stage')
   ; what do we run?
   Local $command = readConfig('execution')
   ; how long do we pause before launching our script?
   Local $launchDelay = Int(readConfig('delay'))
   ; do we reboot?
   Local $reboot = readConfig('reboot')

   ; we only use a while loop so we can easily break out of the switch statement
   While $bServiceRunning

   Switch ($rebootcount)
	  Case $CCS_BOOT_COUNT
		 ; launch the cmd script
		 WriteLog('Deployment stage: ' & $rebootcount)
		 writeConfig('stage', $rebootcount + 1) ; update to push it past our allowed value

		 ; finally, launch our customization script, if provided
		 If $command <> '' Then
			If FileExists($command) Then
			   Sleep($launchDelay)  ; pause
			   WriteLog('Launching "' & $command & '" ...')
			   ; Run the command and wait for it to finish
			   Run(@ComSpec & " /c " & $command, "", @SW_HIDE)
			Else
			   WriteLog('The supplied action, "' & $command & '" could not be found or accessed.')
			EndIf
		 EndIf

		; The command ran, do we reboot?
		 If $reboot Then
			; we need to force a reboot
			WriteLog('Forcing system reboot.')
			WriteEventLog($WE_INFORMATION, 'Rebooting system.')
			Shutdown(BitOR($SD_REBOOT, $SD_FORCE))
		 EndIf

		 ; we're done, so signal end
		 $bServiceRunning = False

	  Case Else
		 writeConfig('stage', $rebootcount + 1) ; update the reboot count
		 $bServiceRunning = False
   EndSwitch

   WEnd

   _Service_ReportStatus($SERVICE_STOP_PENDING, $NO_ERROR, 1000)
   WriteLog("Stopping service.")
   _Service_Stop($sServiceName)

   _Service_ReportStatus($SERVICE_STOPPED, $NO_ERROR, 0)

EndFunc   ;==>_Svc_Main

Func InstallService()

;~ 	Check for Adminstrativee rights
	If Not (IsAdmin()) Then
		MsgBox(0, $sServiceName, "You must have administrative rights to install this as a service.")
		;WriteLog("Admin rights needed, will exit now")
		Exit
	EndIf

	;WriteLog("Installing Service, Please Wait" & @CRLF)
	FileCopy(@ScriptName, @SystemDir & '\' & @ScriptName, 1)
	_Service_Create($sServiceName, $sServiceDisplayName, $SERVICE_WIN32_OWN_PROCESS, $SERVICE_AUTO_START, $SERVICE_ERROR_SEVERE, '"' & @SystemDir & '\' & @ScriptName & '"')

	If @error Then
		WriteLog("Problem Installing Service, Error number is " & @error & @CRLF & " message  : " & _WinAPI_GetLastErrorMessage())
		Return 0
	Else
		WriteLog("Installation of Service Successful.")
	EndIf

	Return 1
	Exit
EndFunc   ;==>InstallService

Func RemoveService()
	_Service_Stop($sServiceName)
	Sleep(30000) ; pause for 30 seconds
	_Service_Delete($sServiceName)
	If Not @error Then WriteLog("Service Removed Successfully" & @CRLF)
	Exit
EndFunc   ;==>RemoveService

Func _exit()
	_Service_ReportStatus($SERVICE_STOPPED, $NO_ERROR, 0);
EndFunc   ;==>_exit

Func _Stopping()
	_Service_ReportStatus($SERVICE_STOP_PENDING, $NO_ERROR, 3000)
EndFunc   ;==>_Stopping

Func _SelfRun($servicename, $action)
	Local $sCmdFile = 'sc ' & $action & ' "' & $servicename & '"'
	Run($sCmdFile, @TempDir, @SW_HIDE)
	Exit
EndFunc   ;==>_SelfRun

Func writeConfig($section, $other)
	Switch ($section)
		Case 'stage'
			IniWrite($configFile, "deployment stage", "state", $other)
	EndSwitch
EndFunc   ;==>writeConfig

Func readConfig($section)
   Local $value = ''
	Switch ($section)
	  Case 'stage'
		 $value = IniRead($configFile, "deployment stage", "state", 0)
	  Case 'execution'
		 $value = IniRead($configFile, "deployment execution", "action", "")
	  Case 'delay'
		 $value = IniRead($configFile, "deployment execution", "delay", 60000) ; default to 1 minute
	  Case 'reboot'
		 $value = IniRead($configFile, "deployment execution", "forcereboot", "FALSE") ; default to no reboot
		 ; normalize $value into a boolean
		 If $value = 'true' Or $value = 'True' Or $value = 'TRUE' Or $value = 1 Or $value = 'yes' Or $value = 'Yes' Or $value = 'YES' Then
			; to simplify, only check for values that cause a reboot
			$value = True
		 Else
			; all other values are considered False
			$value = False
		 EndIf
	EndSwitch
	Return $value
EndFunc   ;==>readConfig

Func WriteEventLog($severity, $message)
   Local $hEventLog, $aData[1] = [0]
   Local $eventMessage = $sServiceName & ': ' & $message
   $hEventLog = _EventLog__Open("", "Application")
   _EventLog__Report($hEventLog, $severity, 0, 2, "", $eventMessage, $aData)
   _EventLog__Close($hEventLog)
EndFunc

; Check the hostname of the system and compare it with a defined value
Func checkHostname($expected)
   ; Update our view of environment variables
   EnvUpdate()
   ; get our current hostname
   Local $compName = @ComputerName
   ; check to see if it matches what we expect
   Local $return = StringCompare($compName, $expected, $STR_NOCASESENSE)
   If  $return = 0 Then
	  Return True
   Else
	  Return False
   EndIf
EndFunc   ;==>checkHostname

; not currently used
Func checkNetwork()
	Local $return = Ping($pingHost, $sleepyTime)
	If $return > 0 Then
		; network is alive
		writeConfig('network', '')
	EndIf
 EndFunc   ;==>checkNetwork

Func getIP()
   ; On the Dimension Data Cloud, all servers are assigned an RFC1918 address on
   ; all NICs. For MCP 1.0 locations, this will always be in the 10.0.0.0/8 space. For
   ; MCP 2.0 locations, it can be in any of the RFC1918 space, 10.0.0.0/8,
   ; 192.168.0.0/16 or 172.16.0.0/12. Our job is to try to determine what this IP is.
   ; In addition, you cannot assign a public IPv4 address directly to a server. You must
   ; always use NAT or VIPs.
   ; There are 4 macros that may contain the IP of the system.

   ; first, create an array using the macros (because AutoIT doesn't have variable interpolation
   Local $ipArray[4]
   $ipArray[0] = @IPAddress1
   $ipArray[1] = @IPAddress2
   $ipArray[2] = @IPAddress3
   $ipArray[3] = @IPAddress4

   Local $ip3 = ''

   ; now loop over the array
   For $ip In $ipArray
	  ; start evaluating the IP
	  $ip3 = StringLeft($ip, 3)
	  If $ip3 = '10.' Or $ip3 = '192' Or $ip3 = 172' Then
		 ; We stop at the first one we find, regardless of how many there may be
		 Return $ip
	  EndIf
   Next

   ; apparently, we didn't find any private addresses, so return "false"
   Return 0

EndFunc

Func updateHostsFile($ipAddress, $hostName)
   ; Update the hosts file with the IP and hostname we require
   Local $file = @SystemDir & "\drivers\etc\hosts"

   Local $fileHandle = FileOpen($file, $FO_OVERWRITE) ;; OVERWRITE existing file!!
   If $fileHandle = -1 Then
	  Return False
   EndIf
   Local $hostLine = '# Hosts file updated by Cloud Config Service' & @CRLF & $ipAddress & @TAB & $hostName & @CRLF
   Local $result = FileWriteLine($fileHandle, $hostLine)
   If $result = 0 Then
	  Return False
   EndIf
   FileClose($fileHandle)
   Return True
EndFunc

Func getVolGUID($volLabel)
   ;; this function iterates over the mounted drives to figure out what
   ;; the volume label is. It does this without regard to drive letter

   ;; get all drives
   Local $drives = DriveGetDrive("FIXED")

   ; Loop over the array holding the drive letters
   For $i = 1 To $drives[0]
	  ; get drive letter and uppercase it
	  Local $currentDrive = StringUpper($drives[$i])
	  ; get this drive's label and uppercase it
	  Local $currentLabel = StringUpper(DriveGetLabel($currentDrive))

	  If $currentLabel = $volLabel Then
		 ;; found it, grab the GUID
		 Local $volGUID = extractVolGUID($currentDrive)
		 Return $volGUID
	  EndIf
   Next

   Return False
EndFunc

Func extractVolGUID($drive)
   ;; get the GUID of the drive
   $drive = $drive & '\' ;; make sure there's a path. a double \\ doesn't hinder execution
   Local $iPID = Run(@ComSpec & ' /C mountvol.exe ' & $drive & ' /L', "", @SW_HIDE, $STDOUT_CHILD)
   ProcessWaitClose($iPID)
   Local $sOutput = StdoutRead($iPID)
   Local $volGUID = StringStripWS($sOutput, $STR_STRIPALL)

   Return $volGUID
EndFunc

#pragma compile(Console, true)
; Change this to 'false' to build a 32-bit binary
#pragma compile(x64, true)
#pragma compile(UPX, true)
' The name of the binary to generate
#pragma compile(Out, cloudconfig.exe)
; The icon to use as the progrma icon (gets jammed into binary)
#pragma compile(Icon, Bogo-D-Project-Disk-iDisk.ico)
; Icon courtesy http://bogo-d.deviantart.com
; Ownership info
#pragma compile(CompanyName, 'Dimension Data')
#pragma compile(FileDescription, 'Cloud Config Service')
#pragma compile(Comments, 'Cloud Config Service')
#pragma compile(FileVersion, 1.3.1.2)
#pragma compile(InternalName, 'CloudConfig')
#pragma compile(LegalCopyright, 'Copyright 2015 Dimension Data')

; We don't need no stinkin' trayicon!
#NoTrayIcon
; Since we will be modifying the system, we need Admin
#RequireAdmin

; Our logging routines
#include "Log.au3"
#include "Misc.au3"
; Routines for interfacing with Service Manager
#include "Services.au3"
#include "StringConstants.au3"
#include <FileConstants.au3>
#include <EventLog.au3>

; Our constants and variables
; The service name(s)
Global Const $sServiceName = "CloudConfig"
Global Const $sServiceDisplayName = "CloudConfig"
; The directory we expect to find our config file and other sundries
Global Const $prepDir = 'C:\CloudConfigService'
; The config file for the service
Global Const $configFile = $prepDir & '\CloudConfig.ini'
; We extract the command from the config file and jam it in this variable
Global $command = ''
; This is the number of boots the system has performed (as extracted from
; the config file)
Global $rebootcount = 0

; constants for Event log
Global Const $WE_SUCCESS = 0
Global Const $WE_ERROR = 1
Global Const $WE_WARNING = 2
Global Const $WE_INFORMATION = 4
Global Const $WE_SUCCESSAUDIT = 8
Global Const $WE_FAILUREAUDIT = 16

; The CCS_BOOT_COUNT is used to determine when to fire off the customization
; For Priced Software images on the Dimension Data Cloud, the value needs to be
; 2. For 3rd parties making images that can be imported into the Cloud, the value
; needs to be 3 to account for the extra boot that occurs when the image is initially
; imported into the platform.
;
; Uncomment to build for a Priced Software image
;Global Const $CCS_BOOT_COUNT = 2
; Uncomment to build a 3rd party image
Global Const $CCS_BOOT_COUNT = 3

; for future feature expansion, not currently used
Global $pingHost = '256.0.0.1' ; yes, it's an illegal IP. this is by design
Global $sleepyTime = 5000 ; Ping timeout, in milliseconds
Global $oldHostname = ''

If Not @Compiled Then Exit
If Not _Singleton(@ScriptName, 1) Then
   If $cmdline[0] > 0 Then
	  If $cmdline[1] = "finish" Then
		 WriteLog("Removing service.")
		 RemoveService()
	  Else
		 WriteLog("Unrecognized command. Terminating due to multiple instances.")
	  EndIf
	  Exit
   EndIf
   WriteLog("Multiple instances running. Terminating.")
   Exit
EndIf

If $cmdline[0] > 0 Then
	Switch $cmdline[1]
		Case "install", "-i", "/i"
			InstallService()
		Case "remove", "-u", "/u", "uninstall"
			RemoveService()
		Case "run", "-r", "/r", "start"
			_SelfRun($sServiceName, "start")
		Case "stop", "-s", "/s"
			_SelfRun($sServiceName, "stop")
		Case Else
			;WriteLog(" - - - Help - - - " & @crlf)
			;WriteLog(" Service Example Params : " & @crlf)
			;WriteLog("  -i : Installs service" & @crlf)
			;WriteLog("  -u : Removes service" & @crlf)
			;WriteLog("  -r : Runs the service" & @crlf)
			;WriteLog("  -s : Stops the service" & @crlf)
			;WriteLog(" - - - - - - - - " & @crlf)
			Exit
	EndSwitch
Else
	If Not _Service_Exists($sServiceName) Then
		If MsgBox(20, "Service Not Installed.", "Would you like to install this service?" & @CRLF & $sServiceName) = 6 Then
			If InstallService() Then
				If MsgBox(4, $sServiceName, "Service Installed Successfully." & @CRLF & "Do you wish to start the process?") = 6 Then _SelfRun($sServiceName, "start")
			EndIf
		Else
			Exit
		EndIf
	EndIf
EndIf

_Service_Init($sServiceName)
Exit

Func _main($iArg, $sArgs)

   Local $hostNameChanged = False

   If Not _Service_ReportStatus($SERVICE_RUNNING, $NO_ERROR, 0) Then
	  WriteLog("Error sending running status, exiting")
	  _Service_ReportStatus($SERVICE_STOPPED, _WinAPI_GetLastError(), 0)
	Exit
   EndIf

   If Not FileExists($configFile) Then
	  ; if we don't have our config file, we abort all operations
	  WriteLog('No config file present. Aborting.')
	  WriteEventLog($WE_ERROR, 'No config file present.')
	  _Service_ReportStatus($SERVICE_STOPPED, _WinAPI_GetLastError(), 0)
	Exit
   EndIf

   Local $bServiceRunning = True ; REQUIRED

   ; how many reboots have we performed?
   Local $rebootcount = readConfig('stage')
   ; what do we run?
   Local $command = readConfig('execution')
   ; how long do we pause before launching our script?
   Local $launchDelay = Int(readConfig('delay'))
   ; do we reboot?
   Local $reboot = readConfig('reboot')

   ; we only use a while loop so we can easily break out of the switch statement
   While $bServiceRunning

   Switch ($rebootcount)
	  Case $CCS_BOOT_COUNT
		 ; launch the cmd script
		 WriteLog('Deployment stage: ' & $rebootcount)
		 writeConfig('stage', $rebootcount + 1) ; update to push it past our allowed value

		 ; finally, launch our customization script, if provided
		 If $command <> '' Then
			If FileExists($command) Then
			   Sleep($launchDelay)  ; pause
			   WriteLog('Launching "' & $command & '" ...')
			   ; Run the command and wait for it to finish
			   Run(@ComSpec & " /c " & $command, "", @SW_HIDE)
			Else
			   WriteLog('The supplied action, "' & $command & '" could not be found or accessed.')
			EndIf
		 EndIf

		; The command ran, do we reboot?
		 If $reboot Then
			; we need to force a reboot
			WriteLog('Forcing system reboot.')
			WriteEventLog($WE_INFORMATION, 'Rebooting system.')
			Shutdown(BitOR($SD_REBOOT, $SD_FORCE))
		 EndIf

		 ; we're done, so signal end
		 $bServiceRunning = False

	  Case Else
		 writeConfig('stage', $rebootcount + 1) ; update the reboot count
		 $bServiceRunning = False
   EndSwitch

   WEnd

   _Service_ReportStatus($SERVICE_STOP_PENDING, $NO_ERROR, 1000)
   WriteLog("Stopping service.")
   _Service_Stop($sServiceName)

   _Service_ReportStatus($SERVICE_STOPPED, $NO_ERROR, 0)

EndFunc   ;==>_Svc_Main

Func InstallService()

;~ 	Check for Adminstrativee rights
	If Not (IsAdmin()) Then
		MsgBox(0, $sServiceName, "You must have administrative rights to install this as a service.")
		;WriteLog("Admin rights needed, will exit now")
		Exit
	EndIf

	;WriteLog("Installing Service, Please Wait" & @CRLF)
	FileCopy(@ScriptName, @SystemDir & '\' & @ScriptName, 1)
	_Service_Create($sServiceName, $sServiceDisplayName, $SERVICE_WIN32_OWN_PROCESS, $SERVICE_AUTO_START, $SERVICE_ERROR_SEVERE, '"' & @SystemDir & '\' & @ScriptName & '"')

	If @error Then
		WriteLog("Problem Installing Service, Error number is " & @error & @CRLF & " message  : " & _WinAPI_GetLastErrorMessage())
		Return 0
	Else
		WriteLog("Installation of Service Successful.")
	EndIf

	Return 1
	Exit
EndFunc   ;==>InstallService

Func RemoveService()
	_Service_Stop($sServiceName)
	Sleep(30000) ; pause for 30 seconds
	_Service_Delete($sServiceName)
	If Not @error Then WriteLog("Service Removed Successfully" & @CRLF)
	Exit
EndFunc   ;==>RemoveService

Func _exit()
	_Service_ReportStatus($SERVICE_STOPPED, $NO_ERROR, 0);
EndFunc   ;==>_exit

Func _Stopping()
	_Service_ReportStatus($SERVICE_STOP_PENDING, $NO_ERROR, 3000)
EndFunc   ;==>_Stopping

Func _SelfRun($servicename, $action)
	Local $sCmdFile = 'sc ' & $action & ' "' & $servicename & '"'
	Run($sCmdFile, @TempDir, @SW_HIDE)
	Exit
EndFunc   ;==>_SelfRun

Func writeConfig($section, $other)
	Switch ($section)
		Case 'stage'
			IniWrite($configFile, "deployment stage", "state", $other)
	EndSwitch
EndFunc   ;==>writeConfig

Func readConfig($section)
   Local $value = ''
	Switch ($section)
	  Case 'stage'
		 $value = IniRead($configFile, "deployment stage", "state", 0)
	  Case 'execution'
		 $value = IniRead($configFile, "deployment execution", "action", "")
	  Case 'delay'
		 $value = IniRead($configFile, "deployment execution", "delay", 60000) ; default to 1 minute
	  Case 'reboot'
		 $value = IniRead($configFile, "deployment execution", "forcereboot", "FALSE") ; default to no reboot
		 ; normalize $value into a boolean
		 If $value = 'true' Or $value = 'True' Or $value = 'TRUE' Or $value = 1 Or $value = 'yes' Or $value = 'Yes' Or $value = 'YES' Then
			; to simplify, only check for values that cause a reboot
			$value = True
		 Else
			; all other values are considered False
			$value = False
		 EndIf
	EndSwitch
	Return $value
EndFunc   ;==>readConfig

Func WriteEventLog($severity, $message)
   Local $hEventLog, $aData[1] = [0]
   Local $eventMessage = $sServiceName & ': ' & $message
   $hEventLog = _EventLog__Open("", "Application")
   _EventLog__Report($hEventLog, $severity, 0, 2, "", $eventMessage, $aData)
   _EventLog__Close($hEventLog)
EndFunc

; Check the hostname of the system and compare it with a defined value
Func checkHostname($expected)
   ; Update our view of environment variables
   EnvUpdate()
   ; get our current hostname
   Local $compName = @ComputerName
   ; check to see if it matches what we expect
   Local $return = StringCompare($compName, $expected, $STR_NOCASESENSE)
   If  $return = 0 Then
	  Return True
   Else
	  Return False
   EndIf
EndFunc   ;==>checkHostname

; not currently used
Func checkNetwork()
	Local $return = Ping($pingHost, $sleepyTime)
	If $return > 0 Then
		; network is alive
		writeConfig('network', '')
	EndIf
 EndFunc   ;==>checkNetwork

Func getIP()
   ; On the Dimension Data Cloud, all servers are assigned an RFC1918 address on
   ; all NICs. For MCP 1.0 locations, this will always be in the 10.0.0.0/8 space. For
   ; MCP 2.0 locations, it can be in any of the RFC1918 space, 10.0.0.0/8,
   ; 192.168.0.0/16 or 172.16.0.0/12. Our job is to try to determine what this IP is.
   ; In addition, you cannot assign a public IPv4 address directly to a server. You must
   ; always use NAT or VIPs.
   ; There are 4 macros that may contain the IP of the system.

   ; first, create an array using the macros (because AutoIT doesn't have variable interpolation
   Local $ipArray[4]
   $ipArray[0] = @IPAddress1
   $ipArray[1] = @IPAddress2
   $ipArray[2] = @IPAddress3
   $ipArray[3] = @IPAddress4

   Local $ip3 = ''

   ; now loop over the array
   For $ip In $ipArray
	  ; start evaluating the IP
	  $ip3 = StringLeft($ip, 3)
	  If $ip3 = '10.' Or $ip3 = '192' Or $ip3 = 172' Then
		 ; We stop at the first one we find, regardless of how many there may be
		 Return $ip
	  EndIf
   Next

   ; apparently, we didn't find any private addresses, so return "false"
   Return 0

EndFunc

Func updateHostsFile($ipAddress, $hostName)
   ; Update the hosts file with the IP and hostname we require
   Local $file = @SystemDir & "\drivers\etc\hosts"

   Local $fileHandle = FileOpen($file, $FO_OVERWRITE) ;; OVERWRITE existing file!!
   If $fileHandle = -1 Then
	  Return False
   EndIf
   Local $hostLine = '# Hosts file updated by Cloud Config Service' & @CRLF & $ipAddress & @TAB & $hostName & @CRLF
   Local $result = FileWriteLine($fileHandle, $hostLine)
   If $result = 0 Then
	  Return False
   EndIf
   FileClose($fileHandle)
   Return True
EndFunc

Func getVolGUID($volLabel)
   ;; this function iterates over the mounted drives to figure out what
   ;; the volume label is. It does this without regard to drive letter

   ;; get all drives
   Local $drives = DriveGetDrive("FIXED")

   ; Loop over the array holding the drive letters
   For $i = 1 To $drives[0]
	  ; get drive letter and uppercase it
	  Local $currentDrive = StringUpper($drives[$i])
	  ; get this drive's label and uppercase it
	  Local $currentLabel = StringUpper(DriveGetLabel($currentDrive))

	  If $currentLabel = $volLabel Then
		 ;; found it, grab the GUID
		 Local $volGUID = extractVolGUID($currentDrive)
		 Return $volGUID
	  EndIf
   Next

   Return False
EndFunc

Func extractVolGUID($drive)
   ;; get the GUID of the drive
   $drive = $drive & '\' ;; make sure there's a path. a double \\ doesn't hinder execution
   Local $iPID = Run(@ComSpec & ' /C mountvol.exe ' & $drive & ' /L', "", @SW_HIDE, $STDOUT_CHILD)
   ProcessWaitClose($iPID)
   Local $sOutput = StdoutRead($iPID)
   Local $volGUID = StringStripWS($sOutput, $STR_STRIPALL)

   Return $volGUID
EndFunc


Update GuiCreateEx.au3

Update GuiCreateEx.au3

#include-once
#include <Array.au3>
#include <GUIConstantsEx.au3>

OnAutoItExitRegister("_GUICreateEx_OnExit")

Opt("GUIOnEventMode", 1)
Opt("GUIEventOptions", 1)
Opt("MustDeclareVars", 1)

Global $g__aGuiCreateEx[1] = [0]

#cs
; Example
#include-once
#include <GuiCreateEx.au3>

Global $hGui
Global $hButton_NewGui

$hGui = GUICreateEx("Título[ " & $g__aGuiCreateEx[0] & " ]", 800, 600)
$hButton_NewGui = GUICtrlCreateButton("new gui", 10, 10, 80, 20)
GUICtrlSetOnEvent($hButton_NewGui, "NewGui")
GUISetState(@SW_SHOW, $hGui)

While Sleep(25)
WEnd

Func NewGui()
	Local $aSize = WinGetPos($g__aGuiCreateEx[UBound($g__aGuiCreateEx, 1) - 1])
	Local $hGui = GUICreateEx("Título[ " & $g__aGuiCreateEx[0] & " ]", $aSize[2] - (20 + 6), $aSize[3] - (40 + 5), $aSize[0] + 10, $aSize[1] + 10, Default, Default, $g__aGuiCreateEx[UBound($g__aGuiCreateEx, 1) - 1])
	$hButton_NewGui = GUICtrlCreateButton("new gui", 10, 10, 80, 20)
	GUICtrlSetOnEvent($hButton_NewGui, "NewGui")
	GUISetState(@SW_SHOW, $hGui)
EndFunc   ;==>NewGui
#ce

; #FUNCTION# ====================================================================================================================
; Name...........:	GUICreateEx
; Description ...:	Allow create a new GUI (Graphic User Interface) above current GUI and lock previus GUI
; Syntax.........:	same way of GuiCreate
; Parameters ....:	$sTitle.......: Title's GUI
;					$iWidth.......:	width's GUI
;					$iHeight......: height's GUI
;					$iLeft........:	left position's GUI
; 					$iTop.........: top position's GUI
;					$mStyle.......:	Style's GUI
;					$mExStyle.....:	Extended Style's GUI
;					$iParent......: The handle of another previously created window
; Return values .:	a windows handle
; Author ........:	Luismar Chechelaky
; Modified.......:	2015/06/20 11:25
; Remarks .......:
; Related .......:
; Link ..........:	https://github.com/chechelaky/AutoIt/blob/master/GuiCreateEx/GuiCreateEx.au3
; Example .......:
; ===============================================================================================================================
Func GUICreateEx($sTitle = "", $iWidth = 460, $iHeight = 360, $iLeft = -1, $iTop = -1, $mStyle = Default, $mExStyle = Default, $iParent = 0)
	If Not $g__aGuiCreateEx[0] Then
		$iParent = 0
	Else
		$iParent = $g__aGuiCreateEx[UBound($g__aGuiCreateEx, 1) - 1]
		GUISetState(@SW_DISABLE, $iParent)
	EndIf
	Local $hGui = GUICreate($sTitle, $iWidth, $iHeight, $iLeft, $iTop, $mStyle, $mExStyle, $iParent)
	If @error Then Return SetError(1, 0, 0)
	GUISetOnEvent($GUI_EVENT_CLOSE, "_GUICreateEx_Quit")
	_ArrayAdd($g__aGuiCreateEx, $hGui)
	$g__aGuiCreateEx[0] = UBound($g__aGuiCreateEx, 1) - 1
	Return $g__aGuiCreateEx[$g__aGuiCreateEx[0]]
EndFunc   ;==>GUICreateEx

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........:	_GUICreateEx_OnExit
; Author ........:	Luismar Chechelaky
; Modified.......:	2015/06/20 11:25
; Link ..........:	https://github.com/chechelaky/AutoIt/blob/master/GuiCreateEx/GuiCreateEx.au3
; ===============================================================================================================================
Func _GUICreateEx_OnExit()
	GUISetState($g__aGuiCreateEx[1], @SW_HIDE)
	GUIDelete($g__aGuiCreateEx[1])
EndFunc   ;==>_GUICreateEx_OnExit

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........:	_GUICreateEx_Quit
; Author ........:	Luismar Chechelaky
; Modified.......:	2015/06/20 11:25
; Link ..........:	https://github.com/chechelaky/AutoIt/blob/master/GuiCreateEx/GuiCreateEx.au3
; ===============================================================================================================================
Func _GUICreateEx_Quit()
	Local $hGui
	Switch $g__aGuiCreateEx[0]
		Case 1
			$hGui = $g__aGuiCreateEx[$g__aGuiCreateEx[0]]
			Exit
		Case Else
			GUISetState(@SW_ENABLE, $g__aGuiCreateEx[$g__aGuiCreateEx[0] - 1])
			GUISetState($g__aGuiCreateEx[$g__aGuiCreateEx[0]], @SW_HIDE)
			GUIDelete($g__aGuiCreateEx[$g__aGuiCreateEx[0]])
			_ArrayDelete($g__aGuiCreateEx, UBound($g__aGuiCreateEx, 1) - 1)
			$g__aGuiCreateEx[0] = UBound($g__aGuiCreateEx, 1) - 1
	EndSwitch
EndFunc   ;==>_GUICreateEx_Quit


Update Exemplo_001.au3

Update Exemplo_001.au3

#include-once
#include <Array.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <StaticConstants.au3>
#include <GuiTreeView.au3>
#include <TreeViewConstants.au3>
#include <GuiMenu.au3>
#include <WinAPI.au3>
#include <SQLite.au3>
#include <SQLite.dll.au3>

#include <GUICreateEx.au3> ; https://github.com/chechelaky/AutoIt/blob/master/GuiCreateEx/GuiCreateEx.au3
#include <JSMN.au3> ; https://github.com/chechelaky/AutoIt/blob/master/JSMN.au3
#include <object_dump.au3> ; https://github.com/chechelaky/AutoIt/blob/master/object_dump.au3

#cs
	Exemplo de uso com TreeView
	Implementando/refatorando código...

	Autor: Luismar Chechelaky
#ce

Opt("GUIOnEventMode", 1)
Opt("GUIEventOptions", 1)
Opt("MustDeclareVars", 1)

OnAutoItExitRegister("OnExit")

HotKeySet("{F2}", "Key_Edit_Start")

Global $KEY_EDIT = False

Global $ID = 0

Global Const $SQLITE_DLL = _SQLite_Startup("sqlite3.dll", False, 0)
Global $DB = _SQLite_Open("base.db", $SQLITE_OPEN_READWRITE + $SQLITE_OPEN_CREATE, $SQLITE_ENCODING_UTF8)
Global $SQL

Global $hGui, $hTreeView, $Context, $hMenu
Global Enum $ONE = 0, $TWO, $TREE
Global $aName[3] = ["A", "B", "C"]
Global $a_TreeView[3]
Global $ah_TreeView[3]
Global $hTreeView_Focus, $TreeView_ID
Global $hTreeView_Focus_Item_Handle, $hTreeView_Focus_Item_Text, $hTreeView_Focus_Item_Param
Global $hLable_TreeView_Focus_Handle, $hLabel_TreeView_Focus_Text, $hLabel_TreeView_Focus_Param

Global $iStyle = BitOR($TVS_EDITLABELS, $TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT, $TVS_DISABLEDRAGDROP, $TVS_SHOWSELALWAYS, $TVS_CHECKBOXES)

$hGui = GUICreateEx("TreeView", 1266, 668); , 550, 0)
_GUICreateEx_SetShortCut("KEY_EDIT", "Key_Edit_End")

$a_TreeView[$ONE] = _GUICtrlTreeView_Create($hGui, 10, 10, 300, 450, $iStyle, $WS_EX_CLIENTEDGE)
$ah_TreeView[$ONE] = ControlGetHandle($hGui, "", $a_TreeView[$ONE])

$a_TreeView[$TWO] = _GUICtrlTreeView_Create($hGui, 10 + 410, 10, 300, 450, $iStyle, $WS_EX_CLIENTEDGE)
$ah_TreeView[$TWO] = ControlGetHandle($hGui, "", $a_TreeView[$TWO])

$a_TreeView[$TREE] = _GUICtrlTreeView_Create($hGui, 10 + 820, 10, 300, 450, $iStyle, $WS_EX_CLIENTEDGE)
$ah_TreeView[$TREE] = ControlGetHandle($hGui, "", $a_TreeView[$TREE])

$hLable_TreeView_Focus_Handle = GUICtrlCreateLabel("", 10, 470, 80, 20, $SS_SUNKEN)
$hLabel_TreeView_Focus_Text = GUICtrlCreateLabel("", 10, 500, 80, 20, $SS_SUNKEN)
$hLabel_TreeView_Focus_Param = GUICtrlCreateLabel("", 10, 530, 80, 20, $SS_SUNKEN)

Global $hParent, $hItem

For $ii = 0 To 2
	$ID += 1
	_GUICtrlTreeView_BeginUpdate($a_TreeView[$ii])
	$hParent = _GUICtrlTreeView_Add($a_TreeView[$ii], 0, "root")
	_GUICtrlTreeView_SetItemParam($a_TreeView[$ii], $hParent, $ID)
	For $jj = 0 To 9
		$ID += 1
		$hItem = _GUICtrlTreeView_AddChild($a_TreeView[$ii], $hParent, $aName[$ii] & $jj)
		_GUICtrlTreeView_SetItemParam($a_TreeView[$ii], $hItem, $ID)
		_GUICtrlTreeView_Expand($a_TreeView[$ii], $hItem)
	Next
	_GUICtrlTreeView_EndUpdate($a_TreeView[$ii])
Next

Global $aButtons[4] = [3, 0, 0, 0]

Global $iDummy = GUICtrlCreateDummy()
$Context = GUICtrlCreateContextMenu($iDummy)
$hMenu = GUICtrlGetHandle($Context)
$aButtons[1] = GUICtrlCreateMenuItem("Add", $Context)
GUICtrlSetOnEvent($aButtons[1], "Add")
$aButtons[2] = GUICtrlCreateMenuItem("Rename", $Context)
GUICtrlSetOnEvent($aButtons[2], "Rename")
$aButtons[3] = GUICtrlCreateMenuItem("Del", $Context)
GUICtrlSetOnEvent($aButtons[3], "Del")

GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
GUISetState(@SW_SHOW, $hGui)

While Sleep(20)

WEnd

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........:	OnExit
; Author ........:	Luismar Chechelaky
; Modified.......:	2016/08/21 17:00
; Link ..........:
; ===============================================================================================================================
Func OnExit()
	_SQLite_Shutdown()
EndFunc   ;==>OnExit

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........:	Key_Edit_Start
; Author ........:	Luismar Chechelaky
; Modified.......:	2016/08/21 17:00
; Link ..........:
; ===============================================================================================================================
Func Key_Edit_Start()
	ConsoleWrite("Key_Edit_Start()" & @LF)
	$hItem = _GUICtrlTreeView_GetSelection($hTreeView_Focus)
	$KEY_EDIT = True
	HotKeySet("{ENTER}", "Key_Edit_Confirm")

	_GUICtrlTreeView_EditText($hTreeView_Focus, $hItem)
EndFunc   ;==>Key_Edit_Start

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........:	Key_Edit_End
; Author ........:	Luismar Chechelaky
; Modified.......:	2016/08/21 17:00
; Link ..........:
; ===============================================================================================================================
Func Key_Edit_End()
	ConsoleWrite("Key_Edit_End()" & @LF)
	HotKeySet("{ENTER}")
	$KEY_EDIT = False
	_GUICtrlTreeView_EndEdit($hTreeView_Focus)
EndFunc   ;==>Key_Edit_End

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........:	Key_Edit_Confirm
; Author ........:	Luismar Chechelaky
; Modified.......:	2016/08/21 17:00
; Link ..........:
; source.........: http://azjio.narod.ru/autoit3_docs/libfunctions/_guictrltreeview_endedit.htm
; ===============================================================================================================================
Func Key_Edit_Confirm()
	Local $hFocus = _GUICtrlTreeView_GetSelection($hTreeView_Focus)
	Local $hEdit = _GUICtrlTreeView_GetEditControl($hTreeView_Focus)
	_GUICtrlTreeView_SetText($hTreeView_Focus, $hItem, ControlGetText($hGui, "", $hEdit))
	HotKeySet("{ENTER}")
	$KEY_EDIT = False
	_GUICtrlTreeView_EndEdit($hTreeView_Focus)
EndFunc   ;==>Key_Edit_Confirm

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........:	Add
; Author ........:	Luismar Chechelaky
; Modified.......:	2016/08/21 17:00
; Link ..........:
; ===============================================================================================================================
Func Add()
	ConsoleWrite("Add" & @LF)

	$ID += 1
	Local $h_Item
	$hItem = _GUICtrlTreeView_GetSelection($hTreeView_Focus)
	If $hItem = 0x00000000 Then
		$h_Item = _GUICtrlTreeView_AddChildFirst($hTreeView_Focus, $hItem, $aName[$TreeView_ID] & $ID)
	Else
		$h_Item = _GUICtrlTreeView_AddChild($hTreeView_Focus, $hItem, $aName[$TreeView_ID] & $ID)
	EndIf
	ConsoleWrite("$hTreeView[ " & $hTreeView_Focus & " ] $hItem[ " & $hItem & " ]" & @LF)
	Local $item = _GUICtrlTreeView_SetItemParam($hTreeView_Focus, $h_Item, $ID)
	ConsoleWrite("item[" & $item & "] $ID[ " & $ID & " ]" & @LF)

	_GUICtrlTreeView_Expand($hTreeView_Focus, $hItem)

EndFunc   ;==>Add

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........:	Rename
; Author ........:	Luismar Chechelaky
; Modified.......:	2016/08/21 17:00
; Link ..........:
; ===============================================================================================================================
Func Rename()
	ConsoleWrite("Rename" & @LF)
EndFunc   ;==>Rename

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........:	Del
; Author ........:	Luismar Chechelaky
; Modified.......:	2016/08/21 17:00
; Link ..........:
; ===============================================================================================================================
Func Del()
	ConsoleWrite("Del" & @LF)

	$hItem = _GUICtrlTreeView_GetSelection($hTreeView_Focus)
	ConsoleWrite("$hItem[ " & $hItem & " ] text[ " & _GUICtrlTreeView_GetText($hTreeView_Focus, $hItem) & " ]" & @LF)

;~ 	Local $sText = _GUICtrlTreeView_GetText($hTreeView_Focus, $hFocus)
;~ 	Local $iParam = _GUICtrlTreeView_GetItemParam($a_TreeView[$ID], $hFocus)

	Local $oo = oo()

	_DelRecursive($hItem, $oo)
	For $each In $oo
		_GUICtrlTreeView_Delete($hTreeView_Focus, $each)
	Next
	dump($oo)
EndFunc   ;==>Del

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........:	_DelRecursive
; Author ........:	Luismar Chechelaky
; Modified.......:	2016/08/21 17:00
; Link ..........:
; ===============================================================================================================================
Func _DelRecursive($handle, ByRef $oo)
	Local $sText = _GUICtrlTreeView_GetText($hTreeView_Focus, $handle)
	Local $iParam = _GUICtrlTreeView_GetItemParam($hTreeView_Focus, $handle)
	Local $oItem = oo()
	$oItem.Add("name", $sText)
	$oItem.Add("param", $iParam)
	Local $hChild
	If _GUICtrlTreeView_GetChildren($hTreeView_Focus, $handle) Then
		$hChild = _GUICtrlTreeView_GetFirstChild($hTreeView_Focus, $handle)
		Do
;~ 			If _GUICtrlTreeView_GetChildren($hTreeView_Focus, $hChild) Then
			_DelRecursive($hChild, $oo)
;~ 			EndIf
			$hChild = _GUICtrlTreeView_GetNextChild($hTreeView_Focus, $hChild)
		Until $hChild = 0
	EndIf
	$oo.Add(Number($handle), $oItem)
EndFunc   ;==>_DelRecursive

;~ Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
;~ 	Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $selitem

;~ 	$tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
;~ 	$hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
;~ 	$iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
;~ 	$iCode = DllStructGetData($tNMHDR, "Code")
;~ 	Switch $hWndFrom
;~ 		Case $a_TreeView[$ONE]
;~ 			Switch $iCode
;~ 				Case $NM_RCLICK
;~ 					$clickPos = _WinAPI_GetMousePos(True, $hGui)
;~ 					$selitem = _GUICtrlTreeView_HitTestItem($a_TreeView[$ONE], DllStructGetData($clickPos, "X"), DllStructGetData($clickPos, "Y")-10)
;~ 					If $selitem = 0 Then Return $GUI_RUNDEFMSG
;~ 					_GUICtrlTreeView_SelectItem($a_TreeView[$ONE], $selitem)

;~ 					_GUICtrlMenu_TrackPopupMenu($hMenu, $hGui)
;~ 			EndSwitch
;~ 	EndSwitch

;~ 	Return $GUI_RUNDEFMSG
;~ EndFunc   ;==>WM_NOTIFY

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........:	_GuiCtrlTreeView_FixFocus
; Author ........:	Luismar Chechelaky
; Modified.......:	2016/08/21 17:00
; Link ..........:
; ===============================================================================================================================
Func _GuiCtrlTreeView_FixFocus($ID, $item = 0)
	ConsoleWrite("_GuiCtrlTreeView_FixFocus()" & @LF)

	Local $hFocus = $item ? $item : _GUICtrlTreeView_GetSelection($a_TreeView[$ID])
	Local $sText = _GUICtrlTreeView_GetText($a_TreeView[$ID], $hFocus)
	Local $iParam = _GUICtrlTreeView_GetItemParam($a_TreeView[$ID], $hFocus)

	GUICtrlSetData($hLable_TreeView_Focus_Handle, $aName[$ID])
	GUICtrlSetData($hLabel_TreeView_Focus_Text, $sText)
	GUICtrlSetData($hLabel_TreeView_Focus_Param, $iParam)

EndFunc   ;==>_GuiCtrlTreeView_FixFocus

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........:	_GuiCtrlTreeView_EvalAction
; Author ........:	Luismar Chechelaky
; Modified.......:	2016/08/21 17:00
; Link ..........:
; ===============================================================================================================================
Func _GuiCtrlTreeView_EvalAction($ID, $tNMHDR, $hWndFrom, $iIDFrom, $iCode, $lParam)
	$TreeView_ID = $ID
	GUICtrlSetData($hLable_TreeView_Focus_Handle, $aName[$ID])
	$hTreeView_Focus = $ah_TreeView[$ID]
	Switch $iCode
		Case $NM_CLICK ; The user has clicked the left mouse button within the control
			_DebugPrint("$NM_CLICK" & @CRLF & "--> hWndFrom:" & @TAB & $hWndFrom & @CRLF & _
					"-->IDFrom:" & @TAB & $iIDFrom & @CRLF & _
					"-->Code:" & @TAB & $iCode)
			; Return 1 ; nonzero to not allow the default processing
			Return 0 ; zero to allow the default processing
		Case $NM_DBLCLK ; The user has double-clicked the left mouse button within the control
			_DebugPrint("$NM_DBLCLK" & @CRLF & "--> hWndFrom:" & @TAB & $hWndFrom & @CRLF & _
					"-->IDFrom:" & @TAB & $iIDFrom & @CRLF & _
					"-->Code:" & @TAB & $iCode)
			; Return 1 ; nonzero to not allow the default processing
			Return 0 ; zero to allow the default processing
		Case $NM_RCLICK ; The user has clicked the right mouse button within the control
			_DebugPrint("$NM_RCLICK" & @CRLF & "--> hWndFrom:" & @TAB & $hWndFrom & @CRLF & _
					"-->IDFrom:" & @TAB & $iIDFrom & @CRLF & _
					"-->Code:" & @TAB & $iCode)
			; Return 1 ; nonzero to not allow the default processing
			_GUICtrlTreeView_SelectItem($hTreeView_Focus, $hTreeView_Focus_Item_Handle)
			_GuiCtrlTreeView_FixFocus($ID, $hTreeView_Focus_Item_Handle)
			_GUICtrlMenu_TrackPopupMenu($hMenu, $hGui)
			Return 0 ; zero to allow the default processing
		Case $NM_RDBLCLK ; The user has double-clicked the right mouse button within the control
			_DebugPrint("$NM_RDBLCLK" & @CRLF & "--> hWndFrom:" & @TAB & $hWndFrom & @CRLF & _
					"-->IDFrom:" & @TAB & $iIDFrom & @CRLF & _
					"-->Code:" & @TAB & $iCode)
			; Return 1 ; nonzero to not allow the default processing
			Return 0 ; zero to allow the default processing
		Case $NM_KILLFOCUS ; control has lost the input focus
			_DebugPrint("$NM_KILLFOCUS" & @CRLF & "--> hWndFrom:" & @TAB & $hWndFrom & @CRLF & _
					"-->IDFrom:" & @TAB & $iIDFrom & @CRLF & _
					"-->Code:" & @TAB & $iCode)
			; No return value
		Case $NM_RETURN ; control has the input focus and that the user has pressed the key
			_DebugPrint("$NM_RETURN" & @CRLF & "--> hWndFrom:" & @TAB & $hWndFrom & @CRLF & _
					"-->IDFrom:" & @TAB & $iIDFrom & @CRLF & _
					"-->Code:" & @TAB & $iCode)
			; Return 1 ; nonzero to not allow the default processing
			Return 0 ; zero to allow the default processing
		Case $NM_SETCURSOR ; control is setting the cursor in response to a WM_SETCURSOR message
			Local $tInfo = DllStructCreate($tagNMMOUSE, $lParam)
			$hWndFrom = HWnd(DllStructGetData($tInfo, "hWndFrom"))
			$iIDFrom = DllStructGetData($tInfo, "IDFrom")
			$iCode = DllStructGetData($tInfo, "Code")

			$hTreeView_Focus_Item_Handle = DllStructGetData($tInfo, "ItemSpec")
			$hTreeView_Focus_Item_Text = _GUICtrlTreeView_GetText($hTreeView_Focus, $hTreeView_Focus_Item_Handle)
			$hTreeView_Focus_Item_Param = _GUICtrlTreeView_GetItemParam($hTreeView_Focus, $hTreeView_Focus_Item_Handle)

			_DebugPrint("$NM_SETCURSOR" & @CRLF & "--> hWndFrom:" & @TAB & $hWndFrom & @CRLF & _
					"-->IDFrom:" & @TAB & $iIDFrom & @CRLF & _
					"-->Code:" & @TAB & $iCode & @CRLF & _
					"-->ItemSpec:" & @TAB & DllStructGetData($tInfo, "ItemSpec") & @CRLF & _
					"-->ItemData:" & @TAB & DllStructGetData($tInfo, "ItemData") & @CRLF & _
					"-->X:" & @TAB & DllStructGetData($tInfo, "X") & @CRLF & _
					"-->Y:" & @TAB & DllStructGetData($tInfo, "Y") & @CRLF & _
					"-->HitInfo:" & @TAB & DllStructGetData($tInfo, "HitInfo"))
			; Return 0 ; to enable the control to set the cursor
			Return 1 ; nonzero to prevent the control from setting the cursor
		Case $NM_SETFOCUS ; control has received the input focus
			_DebugPrint("$NM_SETFOCUS" & @CRLF & "--> hWndFrom:" & @TAB & $hWndFrom & @CRLF & _
					"-->IDFrom:" & @TAB & $iIDFrom & @CRLF & _
					"-->Code:" & @TAB & $iCode)
			; No return value
		Case $TVN_BEGINDRAGA, $TVN_BEGINDRAGW
			_DebugPrint("$TVN_BEGINDRAG")
		Case $TVN_BEGINLABELEDITA, $TVN_BEGINLABELEDITW
			_DebugPrint("$TVN_BEGINLABELEDIT")
		Case $TVN_BEGINRDRAGA, $TVN_BEGINRDRAGW
			_DebugPrint("$TVN_BEGINRDRAG")
		Case $TVN_DELETEITEMA, $TVN_DELETEITEMW
			_DebugPrint("$TVN_DELETEITEM")
		Case $TVN_ENDLABELEDITA, $TVN_ENDLABELEDITW

			ConsoleWrite("Edit Control Handle: 0x" & Hex(_GUICtrlTreeView_GetEditControl($hTreeView_Focus)) & @CRLF & _
					"IsPtr = " & IsPtr(_GUICtrlTreeView_GetEditControl($hTreeView_Focus)) & " IsHWnd = " & IsHWnd(_GUICtrlTreeView_GetEditControl($hTreeView_Focus)))

			Local $tInfo = DllStructCreate($tagNMTVDISPINFO, $lParam)
			Local $sBuffer = DllStructCreate("wchar Text[" & DllStructGetData($tInfo, "TextMax"))
			ConsoleWrite("$sBuffer[ " & $sBuffer & " ]" & @LF)
			If Not _GUICtrlTreeView_GetUnicodeFormat($hWndFrom) Then $sBuffer = StringTrimLeft($sBuffer, 1)
			ConsoleWrite("$sBuffer[ " & $sBuffer & " ]" & @LF)
			DllStructSetData($sBuffer, "Text", DllStructGetData($tInfo, "Text"))

			If StringLen(DllStructGetData($sBuffer, "Text")) Then Return 1

			_DebugPrint("$TVN_ENDLABELEDIT $sBuffer[ " & $sBuffer & " ]")
		Case $TVN_GETDISPINFOA, $TVN_GETDISPINFOW
			_DebugPrint("$TVN_GETDISPINFO")
		Case $TVN_GETINFOTIPA, $TVN_GETINFOTIPW
			_DebugPrint("$TVN_GETINFOTIP")
		Case $TVN_ITEMEXPANDEDA, $TVN_ITEMEXPANDEDW
			_DebugPrint("$TVN_ITEMEXPANDED")
		Case $TVN_ITEMEXPANDINGA, $TVN_ITEMEXPANDINGW
			_DebugPrint("$TVN_ITEMEXPANDING")
		Case $TVN_KEYDOWN
			_DebugPrint("$TVN_KEYDOWN")
		Case $TVN_SELCHANGEDA, $TVN_SELCHANGEDW
			_GuiCtrlTreeView_FixFocus($ID)
			_DebugPrint("$TVN_SELCHANGED")
		Case $TVN_SELCHANGINGA, $TVN_SELCHANGINGW
			_DebugPrint("$TVN_SELCHANGING")
		Case $TVN_SETDISPINFOA, $TVN_SETDISPINFOW
			_DebugPrint("$TVN_SETDISPINFO")
		Case $TVN_SINGLEEXPAND
			_DebugPrint("$TVN_SINGLEEXPAND")
	EndSwitch
EndFunc   ;==>_GuiCtrlTreeView_EvalAction

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........:
; Author ........:
; Modified.......:
; Link ..........:
; ===============================================================================================================================
Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam)
	#forceref $hWnd, $iMsg, $lParam
	Local $tNMHDR, $hWndFrom, $iIDFrom, $iCode

	$tNMHDR = DllStructCreate($tagNMHDR, $lParam)
	$hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
	$iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
	$iCode = DllStructGetData($tNMHDR, "Code")
	Switch $hWndFrom
		Case $ah_TreeView[$ONE]
			_GuiCtrlTreeView_EvalAction($ONE, $tNMHDR, $hWndFrom, $iIDFrom, $iCode, $lParam)
		Case $ah_TreeView[$TWO]
			_GuiCtrlTreeView_EvalAction($TWO, $tNMHDR, $hWndFrom, $iIDFrom, $iCode, $lParam)
		Case $ah_TreeView[$TREE]
			_GuiCtrlTreeView_EvalAction($TREE, $tNMHDR, $hWndFrom, $iIDFrom, $iCode, $lParam)
	EndSwitch
	Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........:	_DebugPrint
; Author ........:
; Modified.......:	2
; Link ..........:
; ===============================================================================================================================
Func _DebugPrint($s_Text, $sLine = @ScriptLineNumber)
	Return
	ConsoleWrite( _
			"!===========================================================" & @CRLF & _
			"+======================================================" & @CRLF & _
			"-->Line(" & StringFormat("%04d", $sLine) & "):" & @TAB & $s_Text & @CRLF & _
			"+======================================================" & @CRLF)
EndFunc   ;==>_DebugPrint

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........:	oo
; Author ........:	Luismar Chechelaky
; Modified.......:	2016/08/21 17:00
; Link ..........:
; ===============================================================================================================================
Func oo()
	Return ObjCreate($SD)
EndFunc   ;==>oo


Update Real.au3

Update Real.au3

; #FUNCTION# ====================================================================================================================
; Version........: 0.0.0.1
; Name...........: Mask/Real
; Description ...: Aplica uma máscara de número real 0.00 em uma entrada numérica
; Syntax.........:
; Parameters ....:
; Return values .:
; Author ........: Luismar Chechelaky
; Creation.......: 2017/12/23
; Modified.......:
; Remarks .......:
; Related .......:
; Link ..........: https://github.com/chechelaky/AutoIt/blob/master/Diversos/Mask/Real.au3
; Example .......: https://github.com/chechelaky/AutoIt/blob/master/Diversos/Mask/Real_Exemplo.au3
; ===============================================================================================================================

Func Real($number = "")
	If $number == "" Then Return ""
	If $number == "." Then Return "0."
	$number = StringRegExpReplace(StringReplace($number, ",", "."), "[^0-9.]", "")
	Local $dot = StringInStr($number, ".")
	If Not $dot Then Return $number
	Return StringReplace(StringMid($number, 1, $dot - 1), ".", "") & "." & StringReplace(StringMid($number, $dot + 1), ".", "")
EndFunc   ;==>Real

; #FUNCTION# ====================================================================================================================
; Version........: 0.0.0.1
; Name...........: Mask/Real
; Description ...: Aplica uma máscara de número real 0.00 em uma entrada numérica
; Syntax.........:
; Parameters ....:
; Return values .:
; Author ........: Luismar Chechelaky
; Creation.......: 2017/12/23
; Modified.......:
; Remarks .......:
; Related .......:
; Link ..........: https://github.com/chechelaky/AutoIt/blob/master/Diversos/Mask/Real.au3
; Example .......: https://github.com/chechelaky/AutoIt/blob/master/Diversos/Mask/Real_Exemplo.au3
; ===============================================================================================================================

Func Real($num = "")
	If $number == "" Then Return ""
	If $number == "." Then Return "0."
	$number = StringRegExpReplace(StringReplace($number, ",", "."), "[^0-9.]", "")
	Local $dot = StringInStr($number, ".")
	If Not $dot Then Return $number
	Return StringReplace(StringMid($number, 1, $dot - 1), ".", "") & "." & StringReplace(StringMid($number, $dot + 1), ".", "")
EndFunc   ;==>Real


Update SampleGUI.au3

Update SampleGUI.au3

#NoTrayIcon

#pragma compile(Out, SampleGUI.exe)
#pragma compile(ExecLevel, highestavailable)
#pragma compile(Compatibility, win7)
#pragma compile(UPX, False)
#pragma compile(FileDescription, SampleGUI for ExpSolver)
#pragma compile(ProductName, ExprSolverGUI)
#pragma compile(ProductVersion, 1.0)
#pragma compile(FileVersion, 1.0.0.0, 1.0.000.0)
#pragma compile(LegalCopyright, Silence Unlimited, Inc)
#pragma compile(LegalTrademarks, '')
#pragma compile(CompanyName, 'Silence Unlimited, Inc')

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include "ExprSolver.au3"

Global Const $dGuiWidth = 400
Global Const $dGuiHeight = 140

Global Const $lpszGithubUrl = "https://github.com/rchockxm"
Global Const $lpszSilenceUnlimitedUrl = "http://rchockxm.com/"

Global Const $lpszExprSolverDll = "..\..\ExprSolver.dll"
Global Const $lpszUseMatchFunc = "ABS,ATN,COS,EXP,FIX,INT,LOG,SIN,SQR,TAN"

Global $gDll = ExprSolverOpen($lpszExprSolverDll, True)

Func ExprSolverErrorToString()
    Local $lpszReturn = ""
    Local $iError = ExprSolver_GetLastError()

    Switch $iError
        Case $T_ERROR_SUCCESS
            $lpszReturn = "Success"
        Case $T_ERROR_EMPTY
            $lpszReturn = "Empty expression"
        Case $T_ERROR_DIVZERO
            $lpszReturn = "Division by zero"
        Case $T_ERROR_TOKEN
            $lpszReturn = "Unknown token type"
        Case $T_ERROR_FUNC
            $lpszReturn = "Math function not found"
        Case $T_ERROR_FUNC_FACTORIAL
            $lpszReturn = "Argument to factorial must be positive"
        Case $T_ERROR_BRACKETS
            $lpszReturn = "Unbalanced round brackets"
    EndSwitch

    Return $lpszReturn
EndFunc

Func BtnExpression($lpszExpression)
    Local $dResult = ExprSolver_Test($lpszExpression)

    Return $dResult
EndFunc

Func WinMain()
    Local $hGUI = GUICreate("ExprSolverGUI", $dGuiWidth, $dGuiHeight)
    Local $hExpression = GUICtrlCreateInput("", 10, 30, $dGuiWidth - 20, 20)
    Local $hResult = GUICtrlCreateInput("", 10, 80, $dGuiWidth - 20, 20)
    Local $hErrorStr = GUICtrlCreateLabel("", 10, $dGuiHeight - 20, 200, 20)
    Local $hRchockxmLink = GUICtrlCreateLabel("Rchockxm", $dGuiWidth - 110, $dGuiHeight - 20, 50, 20)
    Local $hGithubLink = GUICtrlCreateLabel("GitHub", $dGuiWidth - 50, $dGuiHeight - 20, 50, 20)

    GUICtrlCreateLabel("Expression", 10, 10)
    GUICtrlCreateLabel("Result", 10, 60)

    GUISetStyle(BitOR($GUI_SS_DEFAULT_GUI, $WS_SIZEBOX))
    GUISetState(@SW_SHOW, $hGUI)

    Local $iPID

    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                ExitLoop
            Case $GUI_EVENT_RESIZED:
            Case $hExpression:
                Local $lpszExpression = GUICtrlRead($hExpression)
                Local $dResult = BtnExpression($lpszExpression)
                Local $lpszError = ExprSolverErrorToString()

                GUICtrlSetData($hResult, $dResult)
                GUICtrlSetData($hErrorStr, $lpszError)
            Case $hRchockxmLink:
                $iPID = ShellExecute($lpszSilenceUnlimitedUrl)
            Case $hGithubLink:
                $iPID = ShellExecute($lpszGithubUrl)
        EndSwitch
    WEnd

    ExprSolverClose()

    GUIDelete($hGUI)
EndFunc

WinMain()

#NoTrayIcon

#pragma compile(Out, SampleGUI.exe)
#pragma compile(ExecLevel, highestavailable)
#pragma compile(Compatibility, win7)
#pragma compile(UPX, False)
#pragma compile(FileDescription, SampleGUI for ExpSolver)
#pragma compile(ProductName, ExprSolverGUI)
#pragma compile(ProductVersion, 1.0)
#pragma compile(FileVersion, 1.0.0.0, 1.0.000.0)
#pragma compile(LegalCopyright, Silence Unlimited, Inc)
#pragma compile(LegalTrademarks, '')
#pragma compile(CompanyName, 'Silence Unlimited, Inc')

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include "ExprSolver.au3"

Global Const $dGuiWidth = 400
Global Const $dGuiHeight = 140

Global Const $lpszExprSolverDll = "..\..\ExprSolver.dll"
Global Const $lpszUseMatchFunc = "ABS,ATN,COS,EXP,FIX,INT,LOG,SIN,SQR,TAN"

Global $gDll = ExprSolverOpen($lpszExprSolverDll, True)

Func ExprSolverErrorToString()
    Local $lpszReturn = ""
    Local $iError = ExprSolver_GetLastError()

    Switch $iError
        Case $T_ERROR_SUCCESS
            $lpszReturn = "Success"
        Case $T_ERROR_EMPTY
            $lpszReturn = "Empty expression"
        Case $T_ERROR_DIVZERO
            $lpszReturn = "Division by zero"
        Case $T_ERROR_TOKEN
            $lpszReturn = "Unknown token type"
        Case $T_ERROR_FUNC
            $lpszReturn = "Math function not found"
        Case $T_ERROR_FUNC_FACTORIAL
            $lpszReturn = "Argument to factorial must be positive"
        Case $T_ERROR_BRACKETS
            $lpszReturn = "Unbalanced round brackets"
    EndSwitch

    Return $lpszReturn
EndFunc

Func BtnExpression($lpszExpression)
    Local $dResult = ExprSolver_Test($lpszExpression)

    Return $dResult
EndFunc

Func WinMain()
    Local $hGUI = GUICreate("ExprSolverGUI", $dGuiWidth, $dGuiHeight)
    Local $hExpression = GUICtrlCreateInput("", 10, 30, $dGuiWidth - 20, 20)
    Local $hResult = GUICtrlCreateInput("", 10, 80, $dGuiWidth - 20, 20)
    Local $hErrorStr = GUICtrlCreateLabel("", 10, $dGuiHeight - 20, 200, 20)

    GUICtrlCreateLabel("Expression", 10, 10)
    GUICtrlCreateLabel("Result", 10, 60)

    GUISetStyle(BitOR($GUI_SS_DEFAULT_GUI, $WS_SIZEBOX))
    GUISetState(@SW_SHOW, $hGUI)

    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                ExitLoop
            Case $GUI_EVENT_RESIZED:
            Case $hExpression:
                Local $lpszExpression = GUICtrlRead($hExpression)
                Local $dResult = BtnExpression($lpszExpression)
                Local $lpszError = ExprSolverErrorToString()

                GUICtrlSetData($hResult, $dResult)
                GUICtrlSetData($hErrorStr, $lpszError)
        EndSwitch
    WEnd

    ExprSolverClose()

    GUIDelete($hGUI)
EndFunc

WinMain()


timeout shorten

timeout shorten

#include <config.au3>
#include <utils.au3>

Func botStart()
   bluestacksShow()
   btnToggle('start bot', $CLASBOT_WINDOW_TOGGLE_START, 'start bot', 'stop')
EndFunc

Func botStop()
   bluestacksHide()
   btnToggle('stop', $CLASBOT_WINDOW_TOGGLE_START, 'start bot', 'stop')
EndFunc

Func bluestacksShow()
   btnToggle('show bluestacks', $CLASBOT_WINDOW_TOGGLE_HIDE, 'show bluestacks', 'hide bluestacks')
EndFunc

Func bluestacksHide()
   btnToggle('hide bluestacks', $CLASBOT_WINDOW_TOGGLE_HIDE, 'show bluestacks', 'hide bluestacks')
EndFunc

Func btnToggle($action = '', $toggleBtn = '', $textOptionA = '', $textOptionB = '')
   If Not isClashBotRunning() AND Not isLoggedIn() Then
	  msgNotify('err', 'clash bot not running.')
	  ; Not running and not logged in.. Strage state.
	  Return False
   EndIf

   WinActivate($CLASBOT_WINDOW) ; brint to front each toggle. might prevent some odd bugs.

   Local $btnToggleText = ControlGetText($CLASBOT_WINDOW, '', $toggleBtn)

   If ('' == $action) OR ($textOptionA == StringLower($btnToggleText) AND $textOptionA == $action) OR ($textOptionB == StringLower($btnToggleText) AND $textOptionB == $action) Then
	  click($CLASBOT_WINDOW, $toggleBtn)
   Else
	  ; invalid state or already in the requested state.
   EndIf

EndFunc

Func closeClashBotApp()
   Local $hWnd = WinGetHandle($CLASBOT_WINDOW)

   If isClashBotRunning() Then
      WinActivate($CLASBOT_WINDOW)
      WinClose($hWnd);
   EndIf
EndFunc

Func loadClashBotApp()
   Local $hWnd = WinGetHandle($CLASBOT_WINDOW)

   If Not isClashBotRunning() Then
	  runBot()
   ElseIf Not isLoggedIn() Then
	  login()
   Else
	  ; all good.. continue. not extra steps needed.
   EndIf

   WinActivate($CLASBOT_WINDOW) ; bring to front.
EndFunc

Func login()
   WinWait($CLASBOT_WINDOW, '', 10)
   Sleep(1000)

   If Not isLoggedIn() Then
	  click($CLASBOT_WINDOW, $CLASBOT_WINDOW_BTN_LOGIN)
	  closeConfirmationBox()
   EndIf
EndFunc

Func closeConfirmationBox()
   WinWait($CLASBOT_CONFIRM_WINDOW, '', 2);
   WinClose($CLASBOT_CONFIRM_WINDOW);
EndFunc

Func runBot()
   Run($CLASHBOT_PATH & $CLASHBOT_EXEC, $CLASHBOT_PATH)

   login()
EndFunc

Func isLoggedIn()
   WinWait($CLASBOT_WINDOW, '', 4)
   Local $loginBtn = ControlGetHandle($CLASBOT_WINDOW, '', $CLASBOT_WINDOW_BTN_LOGIN);

   If @error AND isClashBotRunning() Then
	  Return True
   Else
	  Return False
   EndIf
EndFunc

Func isClashBotRunning()
   Local $hWnd = WinGetHandle($CLASBOT_WINDOW)

   If @error Then
	  Return False
   Else
	  Return True
   EndIf
EndFunc

Func isStarted()
   If Not isClashBotRunning() AND Not isLoggedIn() Then
	  ; msgNotify('err', 'clash bot not running.')
	  ; Not running and not logged in.. Strage state.
	  Return False
   EndIf

   Local $btnToggleText = ControlGetText($CLASBOT_WINDOW, '', $CLASBOT_WINDOW_TOGGLE_START)

   If 'Stop' == $btnToggleText Then
      Return True
   Else
      Return False
   EndIf
EndFunc

#include <config.au3>
#include <utils.au3>

Func botStart()
   bluestacksShow()
   btnToggle('start bot', $CLASBOT_WINDOW_TOGGLE_START, 'start bot', 'stop')
EndFunc

Func botStop()
   bluestacksHide()
   btnToggle('stop', $CLASBOT_WINDOW_TOGGLE_START, 'start bot', 'stop')
EndFunc

Func bluestacksShow()
   btnToggle('show bluestacks', $CLASBOT_WINDOW_TOGGLE_HIDE, 'show bluestacks', 'hide bluestacks')
EndFunc

Func bluestacksHide()
   btnToggle('hide bluestacks', $CLASBOT_WINDOW_TOGGLE_HIDE, 'show bluestacks', 'hide bluestacks')
EndFunc

Func btnToggle($action = '', $toggleBtn = '', $textOptionA = '', $textOptionB = '')
   If Not isClashBotRunning() AND Not isLoggedIn() Then
	  msgNotify('err', 'clash bot not running.')
	  ; Not running and not logged in.. Strage state.
	  Return False
   EndIf

   WinActivate($CLASBOT_WINDOW) ; brint to front each toggle. might prevent some odd bugs.

   Local $btnToggleText = ControlGetText($CLASBOT_WINDOW, '', $toggleBtn)

   If ('' == $action) OR ($textOptionA == StringLower($btnToggleText) AND $textOptionA == $action) OR ($textOptionB == StringLower($btnToggleText) AND $textOptionB == $action) Then
	  click($CLASBOT_WINDOW, $toggleBtn)
   Else
	  ; invalid state or already in the requested state.
   EndIf

EndFunc

Func closeClashBotApp()
   Local $hWnd = WinGetHandle($CLASBOT_WINDOW)

   If isClashBotRunning() Then
      WinActivate($CLASBOT_WINDOW)
      WinClose($hWnd);
   EndIf
EndFunc

Func loadClashBotApp()
   Local $hWnd = WinGetHandle($CLASBOT_WINDOW)

   If Not isClashBotRunning() Then
	  runBot()
   ElseIf Not isLoggedIn() Then
	  login()
   Else
	  ; all good.. continue. not extra steps needed.
   EndIf

   WinActivate($CLASBOT_WINDOW) ; bring to front.
EndFunc

Func login()
   WinWait($CLASBOT_WINDOW, '', 10)
   Sleep(1000)

   If Not isLoggedIn() Then
	  click($CLASBOT_WINDOW, $CLASBOT_WINDOW_BTN_LOGIN)
	  closeConfirmationBox()
   EndIf
EndFunc

Func closeConfirmationBox()
   WinWait($CLASBOT_CONFIRM_WINDOW, '', 2);
   WinClose($CLASBOT_CONFIRM_WINDOW);
EndFunc

Func runBot()
   Run($CLASHBOT_PATH & $CLASHBOT_EXEC, $CLASHBOT_PATH)

   login()
EndFunc

Func isLoggedIn()
   WinWait($CLASBOT_WINDOW, '', 10)
   Local $loginBtn = ControlGetHandle($CLASBOT_WINDOW, '', $CLASBOT_WINDOW_BTN_LOGIN);

   If @error AND isClashBotRunning() Then
	  Return True
   Else
	  Return False
   EndIf
EndFunc

Func isClashBotRunning()
   Local $hWnd = WinGetHandle($CLASBOT_WINDOW)

   If @error Then
	  Return False
   Else
	  Return True
   EndIf
EndFunc

Func isStarted()
   If Not isClashBotRunning() AND Not isLoggedIn() Then
	  ; msgNotify('err', 'clash bot not running.')
	  ; Not running and not logged in.. Strage state.
	  Return False
   EndIf

   Local $btnToggleText = ControlGetText($CLASBOT_WINDOW, '', $CLASBOT_WINDOW_TOGGLE_START)

   If 'Stop' == $btnToggleText Then
      Return True
   Else
      Return False
   EndIf
EndFunc