#include #include "..\ztna.au3" Local Const $gIniPath = @ScriptDir & "\app-web-portal.ini" Local Const $gSection = "app" ; Read settings Local $debug = StringLower(IniRead($gIniPath, $gSection, "debug", "false")) = "true" Local $tPageLoadWait = Int(IniRead($gIniPath, $gSection, "page-load-wait", "2000")) ; wait after navigation for page to load Local $tAfterSubmitWait = Int(IniRead($gIniPath, $gSection, "after-submit-wait", "4000")) ; wait after each submit Local $tFocusWait = Int(IniRead($gIniPath, $gSection, "focus-wait", "500")) ; small pauses between focus/Send actions Func _KillAllEdge() Local $list = ProcessList("msedge.exe") Local $count = 0 For $i = 1 To $list[0][0] Local $pid = $list[$i][1] ; Close Edge forcibly ProcessClose($pid) $count += 1 Next If $count > 0 Then ConsoleWrite("Closed " & $count & " Edge process(es)." & @CRLF) ; Give Windows a second to clean up window handles Sleep(1000) EndIf EndFunc ; ------------------------ ; Helpers ; ------------------------ Func _PromptIfEmpty(ByRef $var, $prompt, $isPassword = False) If $var = "" Then If $isPassword Then $var = InputBox("Input required", $prompt, "", "", -1, -1, 0, 0) Else $var = InputBox("Input required", $prompt) EndIf If @error Then MsgBox($MB_ICONERROR, "Aborted", "User cancelled input.") Exit EndIf EndIf EndFunc ; ------------------------------------------------- ; Find Microsoft Edge executable path ; ------------------------------------------------- Func _GetEdgePath() Local $path = "" ; Check 64-bit Edge $path = RegRead("HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\msedge.exe", "") If @error Or $path = "" Then ; Check 32-bit Edge on 64-bit Windows $path = RegRead("HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\App Paths\msedge.exe", "") EndIf ; Fallback to common installation folders If $path = "" Then Local $possible[] = [ _ @ProgramFilesDir & "\Microsoft\Edge\Application\msedge.exe", _ @ProgramFilesDir & " (x86)\Microsoft\Edge\Application\msedge.exe", _ @LocalAppDataDir & "\Microsoft\Edge\Application\msedge.exe" _ ] For $i = 0 To UBound($possible) - 1 If FileExists($possible[$i]) Then $path = $possible[$i] ExitLoop EndIf Next EndIf If $path = "" Then Return SetError(1, 0, "") Return $path EndFunc Func _RunEdgeAndWait($url, $timeoutSec = 2) Local $sEdgePath = _GetEdgePath() ; Start Edge in a new window with the URL Local $edgeCmd = '"' & $sEdgePath & '" --new-window "' & $url & '" --no-first-run --disable-features=RestoreSessionState' Local $pid = Run($edgeCmd, "", @SW_SHOWNORMAL) If @error Or $pid = 0 Then MsgBox($MB_ICONERROR, "Error", "Failed to launch Edge. Is msedge.exe in PATH?") Exit EndIf ; Wait roughly until a window with the domain appears (title will usually contain host or company) Local $tEnd = TimerInit() While TimerDiff($tEnd) < $timeoutSec * 1000 ; You can tune the substring used here to match your SSO page title. Use a distinct part of your URL or page title. If WinExists($url) Or WinExists("Sign in") Or WinExists("AWS") Or WinExists("SSO") Or WinExists("Login") Then WinActivate(WinGetHandle("[ACTIVE]")) Return True EndIf Sleep(500) WEnd ; fallback: wait a fixed time then continue Sleep($tPageLoadWait) Return True EndFunc Func ExecuteSequence($seq, ByRef $pairs) Local $actions = StringSplit($seq, ",", $STR_NOCOUNT) For $i = 0 To UBound($actions) - 1 Local $action = StringStripWS($actions[$i], $STR_STRIPLEADING + $STR_STRIPTRAILING) Switch $action Case "{TAB}" Send("{TAB}") Case "{ENTER}" Send("{ENTER}") Case Else If StringLeft($action, 5) = "{var:" And StringRight($action, 1) = "}" Then Local $name = StringTrimRight(StringTrimLeft($action, 5), 1) If MapExists($pairs, $name) Then Local $value = $pairs[$name] Send($value, 1) Else ConsoleWrite("Missing variable in pairs map: " & $name & @CRLF) EndIf ElseIf StringLeft($action, 6) = "{wait:" And StringRight($action, 1) = "}" Then Local $millisecs = StringTrimRight(StringTrimLeft($action, 6), 1) If StringIsInt($millisecs) Then Sleep(Int($millisecs)) Else ConsoleWrite("Invalid wait value: " & $millisecs & @CRLF) EndIf Else ConsoleWrite("Unknown action: " & $action & @CRLF) EndIf EndSwitch Next EndFunc Local $pairs = GetConnectionParams() _KillAllEdge() ; -------------------------- ; Access asset parameters ; -------------------------- Local $script = MapExists($pairs, "Script") ? $pairs["Script"] : "Script" Local $url = $pairs["Host"] Local $seq = IniRead($gIniPath, $gSection, $script, "{USER}") ; --------------------------------- ; Applicaiton specific logic: BEGIN ; --------------------------------- ; --- config --- ; INI format expected (same folder as script): ; [app] ; debug=true AutoItSetOption("WinTitleMatchMode", 2) ; substring matching for Win* functions Opt("SendKeyDelay", 40) Opt("SendKeyDownDelay", 5) If $debug Then Local $text = "" For $key In MapKeys($pairs) Local $value = $pairs[$key] If StringLower($key) = "password" Then $value = "****" EndIf $text &= $key & " = " & $value & @CRLF Next $text &= "Sequence = " & $seq & @CRLF ; Shows popup for 10 seconds, then closes automatically MsgBox(64, "Debug: $pairs values", $text, 10) EndIf ; Launch Edge and navigate _RunEdgeAndWait($url) Sleep($tPageLoadWait) ; Focus the browser (Edge) ; Depending on the environment the title of the window may vary; using generic "msedge" substring match If WinExists("Microsoft Edge") Then WinActivate("Microsoft Edge") Sleep($tFocusWait) EndIf ; Send($company, 1) ; raw mode to send literally ; Sleep($tFocusWait) ; Send("{ENTER}") ; submit company ; Sleep($tAfterSubmitWait) ; Sleep(1000) ExecuteSequence($seq, $pairs) ; --------------------------------- ; Applicaiton specific logic: END ; --------------------------------- UnblockInput()