diff --git a/StartProcessAsCurrentUser.ps1 b/StartProcessAsCurrentUser.ps1 new file mode 100644 index 0000000..e5a10fb --- /dev/null +++ b/StartProcessAsCurrentUser.ps1 @@ -0,0 +1,305 @@ +param( + [Parameter(Mandatory=$true)][string]$Program, + [string]$cmdline = '' +) + +$Source = @" +using System; +using System.Runtime.InteropServices; + +namespace murrayju.ProcessExtensions +{ +public static class ProcessExtensions +{ + #region Win32 Constants + + private const int CREATE_UNICODE_ENVIRONMENT = 0x00000400; + private const int CREATE_NO_WINDOW = 0x08000000; + + private const int CREATE_NEW_CONSOLE = 0x00000010; + + private const uint INVALID_SESSION_ID = 0xFFFFFFFF; + private static readonly IntPtr WTS_CURRENT_SERVER_HANDLE = IntPtr.Zero; + + #endregion + + #region DllImports + + const string SE_TCB_NAME = "SeTcbPrivilege"; + const int SE_PRIVILEGE_ENABLED = 0x00000002; + const int TOKEN_ADJUST_PRIVILEGES = 0x00000020; + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + struct TokPriv1Luid + { + public int Count; + public long Luid; + public int Attr; + } + + [DllImport("Kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] + private static extern Int32 GetLastError(); + + [DllImport("advapi32.dll", EntryPoint = "CreateProcessAsUser", SetLastError = true, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] + private static extern bool CreateProcessAsUser( + IntPtr hToken, + String lpApplicationName, + String lpCommandLine, + IntPtr lpProcessAttributes, + IntPtr lpThreadAttributes, + bool bInheritHandle, + uint dwCreationFlags, + IntPtr lpEnvironment, + String lpCurrentDirectory, + ref STARTUPINFO lpStartupInfo, + out PROCESS_INFORMATION lpProcessInformation); + + [DllImport("advapi32.dll", EntryPoint = "DuplicateTokenEx")] + private static extern bool DuplicateTokenEx( + IntPtr ExistingTokenHandle, + uint dwDesiredAccess, + IntPtr lpThreadAttributes, + int TokenType, + int ImpersonationLevel, + ref IntPtr DuplicateTokenHandle); + + [DllImport("userenv.dll", SetLastError = true)] + private static extern bool CreateEnvironmentBlock(ref IntPtr lpEnvironment, IntPtr hToken, bool bInherit); + + [DllImport("userenv.dll", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + private static extern bool DestroyEnvironmentBlock(IntPtr lpEnvironment); + + [DllImport("kernel32.dll", SetLastError = true)] + private static extern bool CloseHandle(IntPtr hSnapshot); + + [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)] + internal static extern bool OpenProcessToken(IntPtr h, int acc, ref IntPtr phtok); + + [DllImport("kernel32.dll")] + private static extern uint WTSGetActiveConsoleSessionId(); + + [DllImport("Wtsapi32.dll")] + private static extern uint WTSQueryUserToken(uint SessionId, ref IntPtr phToken); + + [DllImport("wtsapi32.dll", SetLastError = true)] + private static extern int WTSEnumerateSessions( + IntPtr hServer, + int Reserved, + int Version, + ref IntPtr ppSessionInfo, + ref int pCount); + + [DllImport("advapi32.dll", SetLastError = true)] + private static extern bool LookupPrivilegeValue(string host, string name, ref long pluid); + + [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)] + private static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall, ref TokPriv1Luid newst, int len, IntPtr prev, IntPtr relen); + + #endregion + + #region Win32 Structs + + private enum SW + { + SW_HIDE = 0, + SW_SHOWNORMAL = 1, + SW_NORMAL = 1, + SW_SHOWMINIMIZED = 2, + SW_SHOWMAXIMIZED = 3, + SW_MAXIMIZE = 3, + SW_SHOWNOACTIVATE = 4, + SW_SHOW = 5, + SW_MINIMIZE = 6, + SW_SHOWMINNOACTIVE = 7, + SW_SHOWNA = 8, + SW_RESTORE = 9, + SW_SHOWDEFAULT = 10, + SW_MAX = 10 + } + + private enum WTS_CONNECTSTATE_CLASS + { + WTSActive, + WTSConnected, + WTSConnectQuery, + WTSShadow, + WTSDisconnected, + WTSIdle, + WTSListen, + WTSReset, + WTSDown, + WTSInit + } + + [StructLayout(LayoutKind.Sequential)] + private struct PROCESS_INFORMATION + { + public IntPtr hProcess; + public IntPtr hThread; + public uint dwProcessId; + public uint dwThreadId; + } + + private enum SECURITY_IMPERSONATION_LEVEL + { + SecurityAnonymous = 0, + SecurityIdentification = 1, + SecurityImpersonation = 2, + SecurityDelegation = 3, + } + + [StructLayout(LayoutKind.Sequential)] + private struct STARTUPINFO + { + public int cb; + public String lpReserved; + public String lpDesktop; + public String lpTitle; + public uint dwX; + public uint dwY; + public uint dwXSize; + public uint dwYSize; + public uint dwXCountChars; + public uint dwYCountChars; + public uint dwFillAttribute; + public uint dwFlags; + public short wShowWindow; + public short cbReserved2; + public IntPtr lpReserved2; + public IntPtr hStdInput; + public IntPtr hStdOutput; + public IntPtr hStdError; + } + + private enum TOKEN_TYPE + { + TokenPrimary = 1, + TokenImpersonation = 2 + } + + [StructLayout(LayoutKind.Sequential)] + private struct WTS_SESSION_INFO + { + public readonly UInt32 SessionID; + + [MarshalAs(UnmanagedType.LPStr)] + public readonly String pWinStationName; + + public readonly WTS_CONNECTSTATE_CLASS State; + } + + #endregion + + // Gets the user token from the currently active session + private static bool GetSessionUserToken(ref IntPtr phUserToken) + { + var bResult = false; + var hImpersonationToken = IntPtr.Zero; + var activeSessionId = INVALID_SESSION_ID; + var pSessionInfo = IntPtr.Zero; + var sessionCount = 0; + + // Get a handle to the user access token for the current active session. + if (WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, ref pSessionInfo, ref sessionCount) != 0) + { + var arrayElementSize = Marshal.SizeOf(typeof(WTS_SESSION_INFO)); + var current = pSessionInfo; + + for (var i = 0; i < sessionCount; i++) + { + var si = (WTS_SESSION_INFO)Marshal.PtrToStructure((IntPtr)current, typeof(WTS_SESSION_INFO)); + current += arrayElementSize; + + if (si.State == WTS_CONNECTSTATE_CLASS.WTSActive) + { + activeSessionId = si.SessionID; + } + } + } + + // If enumerating did not work, fall back to the old method + if (activeSessionId == INVALID_SESSION_ID) + { + activeSessionId = WTSGetActiveConsoleSessionId(); + } + + if (WTSQueryUserToken(activeSessionId, ref hImpersonationToken) != 0) + { + // Convert the impersonation token to a primary token + bResult = DuplicateTokenEx(hImpersonationToken, 0, IntPtr.Zero, + (int)SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, (int)TOKEN_TYPE.TokenPrimary, + ref phUserToken); + + CloseHandle(hImpersonationToken); + } + + return bResult; + } + + public static bool StartProcessAsCurrentUser(string appPath, string cmdLine = null, string workDir = null, bool visible = true) + { + var hUserToken = IntPtr.Zero; + var startInfo = new STARTUPINFO(); + var procInfo = new PROCESS_INFORMATION(); + var pEnv = IntPtr.Zero; + int iResultOfCreateProcessAsUser; + IntPtr LoggedInUserToken = IntPtr.Zero; + + startInfo.cb = Marshal.SizeOf(typeof(STARTUPINFO)); + + try + { + if (!GetSessionUserToken(ref hUserToken)) + { + throw new Exception("StartProcessAsCurrentUser: GetSessionUserToken failed. ErrCode: " + GetLastError().ToString()); + } + + uint dwCreationFlags = CREATE_UNICODE_ENVIRONMENT | (uint)(visible ? CREATE_NEW_CONSOLE : CREATE_NO_WINDOW); + startInfo.wShowWindow = (short)(visible ? SW.SW_SHOW : SW.SW_HIDE); + startInfo.lpDesktop = "winsta0\\default"; + + if (!CreateEnvironmentBlock(ref pEnv, hUserToken, false)) + { + throw new Exception("StartProcessAsCurrentUser: CreateEnvironmentBlock failed."); + } + + if (!CreateProcessAsUser(hUserToken, + appPath, // Application Name + cmdLine, // Command Line + IntPtr.Zero, + IntPtr.Zero, + false, + dwCreationFlags, + pEnv, + workDir, // Working directory + ref startInfo, + out procInfo)) + { + throw new Exception("StartProcessAsCurrentUser: CreateProcessAsUser failed.\n"); + } + + iResultOfCreateProcessAsUser = Marshal.GetLastWin32Error(); + } + finally + { + CloseHandle(hUserToken); + if (pEnv != IntPtr.Zero) + { + DestroyEnvironmentBlock(pEnv); + } + CloseHandle(procInfo.hThread); + CloseHandle(procInfo.hProcess); + } + return true; + } +} +} + + +"@ + + +Add-Type -ReferencedAssemblies 'System', 'System.Runtime.InteropServices' -TypeDefinition $Source -Language CSharp + +[murrayju.ProcessExtensions.ProcessExtensions]::StartProcessAsCurrentUser($Program, $cmdline) \ No newline at end of file diff --git a/test.ps1 b/test.ps1 new file mode 100644 index 0000000..8d168d8 --- /dev/null +++ b/test.ps1 @@ -0,0 +1,221 @@ +param ( + + [Parameter(Mandatory=$false)] + [string]$instanceIP + +) + +if(-not $instanceIP){$instanceIP = "10.0.211.121"} + +$global:LDPlayerPath ="C:\Ldplayer\LDplayer9" + +function logger($logMessage) { + [int]$number = (get-content -path "$global:LDPlayerPath\index_count.txt") + if($number -gt 21){ $number=0} + $instanceList = Get-Content -Path "$global:LDPlayerPath\instanceList.txt" + $instanceNumber = $instanceList[$number] + $instanceData = (cat C:\Ldplayer\LDplayer9\vms\config\leidian${instanceNumber}.config) + $convertedData = $instanceData | ConvertFrom-Json + $name = $convertedData."statusSettings.playerName" + $count = $number+1 + + $scriptName = Split-Path -Leaf $PSCommandPath + $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss.fff" + $timestampedLogMessage = $timestamp + "-$name, ($count/22)-$scriptName-PID: ${PID}-:" + $logMessage + $logFilePath = "$global:LDPlayerPath\LDAutoLog.txt" + $fs = New-Object System.IO.FileStream($logFilePath, [System.IO.FileMode]::Append, [System.IO.FileAccess]::Write, [System.IO.FileShare]::Read) + $sw = New-Object System.IO.StreamWriter($fs) + try { + $sw.WriteLine($timestampedLogMessage) + } finally { + $sw.Close() + $fs.Close() + } + } + +function Get-ScreenshotData($text) { + adb connect $instanceIP *>$null +adb -s $instanceIP exec-out screencap -p > $global:LDPlayerPath\screenshot.png *>$null + + & "C:\Program Files\Tesseract-OCR\tesseract.exe" "$global:LDPlayerPath\screenshot.png" "$global:LDPlayerPath\tesseract" -l eng tsv *>$null + +$tsvFile = "$global:LDPlayerPath\tesseract.tsv" + +$wordCoords = Get-Content $tsvFile | ConvertFrom-Csv -Delimiter "`t" +$wordCoords | Where-Object ($_.level -eq 5) | Select-Object text, left, top, width, height + + +$Data = $wordCoords | ForEach-Object { + $x1 =[int]$_._left + $y1 =[int]$_.top + $width = [int]$_.width + $height = [int]$_.height + + $midX =[math]::Round($x1+$width/2) + $midY =[math]::Round($y1+$height/2) + + [PSCustomObject]@{ + Text = $_.text + Coords = "$midX $midY" + } +} +$Element = $Data | Where-Object {$_.Text -and $_.Text.ToLower() -eq $text} + +$coordsForText=$Element.Coords +return $coordsForText +} + +function Find-Element($xml, $keyword) { + if (-not $xml -is [System.Xml.XmlDocument] -or -not $keyword) { return $null } + $sanitizedKeyword = $keyword.Replace("'", "''").ToLower() + $query = "//node[contains(translate(@text, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), '$sanitizedKeyword') or contains(translate(@content-desc, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), '$sanitizedKeyword')]" + return $xml.SelectSingleNode($query) +} + + +function Wait-For-ScreenChange($adbTarget, $initialHash, [ref]$newXmlData) { + $xmlContent = Get-Content -Raw -Path "$global:LDPlayerPath\screen.xml" -Encoding UTF8 + $Xml = [xml]$xmlContent + $Hash = (Get-FileHash -Algorithm MD5 -InputStream ([System.IO.MemoryStream]::new([System.Text.Encoding]::UTF8.GetBytes($xmlContent)))).Hash + $timeoutSeconds = 10 + logger("Aguardando alteração na tela (timeout de $timeoutSeconds segundos)...") + $stopwatch = [System.Diagnostics.Stopwatch]::StartNew() + while ($stopwatch.Elapsed.TotalSeconds -lt $timeoutSeconds) { + $currentScreenData = Get-ScreenData -adbTarget $adbTarget + if ($currentScreenData -and $currentScreenData.Hash -ne $initialHash) { + $stopwatch.Stop(); logger("Tela alterada! Prosseguindo..."); $newXmlData.Value = $currentScreenData; return $true + } + Start-Sleep -Seconds 1 + } + $stopwatch.Stop(); logger("TIMEOUT: A tela não mudou após $timeoutSeconds segundos."); return $false +} + +function Invoke-TapAction($adbTarget, $xml, $keyword) { + $element = Find-Element -xml $xml -keyword $keyword + if (-not $element) { logger("Elemento '$keyword' para tocar não foi encontrado."); return $false } + $bounds = $element.bounds + if ($bounds -notmatch '\[(\d+),(\d+)\]\[(\d+),(\d+)\]') { logger("Formato de 'bounds' inválido: $bounds"); return } + $xMid = ([int]$Matches[1] + [int]$Matches[3]) / 2 + $yMid = ([int]$Matches[2] + [int]$Matches[4]) / 2 + logger("Ação: Tocando em '$($element.text)'...") + adb -s $instanceIP shell input tap "$xMid $yMid" *>$null + return +} + +function Handle-SystemDialogs() { + $xmlContent = Get-Content -Raw -Path "$global:LDPlayerPath\screen.xml" -Encoding UTF8 + $Xml = [xml]$xmlContent + $Hash = (Get-FileHash -Algorithm MD5 -InputStream ([System.IO.MemoryStream]::new([System.Text.Encoding]::UTF8.GetBytes($xmlContent)))).Hash + # Verifica se o diálogo "não está a responder" (ANR) está na tela + + if ((Find-Element -xml $xml -keyword "não está a responder") -or (Find-Element -xml $xml -keyword "UI not responsive")) { + logger("Detectado diálogo 'IU não está a responder'. Tentando tocar em 'Aguardar'.") + $initialHash = $Hash + + if (Find-Element -xml $xml -keyword "Aguardar") { + $tappedWait = Invoke-TapAction -adbTarget $adbTarget -xml $xml -keyword "Aguardar" + } else { + $tappedWait = Invoke-TapAction -adbTarget $adbTarget -xml $xml -keyword "wait" + } + + if ($tappedWait) { + # Espera o diálogo desaparecer + $dialogDismissed = Wait-For-ScreenChange -initialHash $initialHash -newXmlData ([ref]$screenData) + if (-not $dialogDismissed) { + logger("Tocou em 'Aguardar', mas o diálogo não desapareceu.") + } + return $true # Indica que um diálogo foi tratado e o passo deve ser repetido + } else { + logger("Diálogo ANR detectado, mas o botão 'Aguardar' não foi encontrado.") + return + } + } + logger("Não houve irresponsividade") + return +} + +function Get-ScreenData() { + for ($attempt = 1; $attempt -le 3; $attempt++) { + try { + logger("Capturando hierarquia da UI (Tentativa $attempt)...") + Start-Sleep -Milliseconds 250 + + + + logger("$dumpOutput") + $cnt=0 + while($true){ + + logger("tentando fazer dump") + logger("iteration: $cnt") + #start-process "adb" -ArgumentList "-s $instanceIP shell uiautomator dump" -RedirectStandardOutput $global:LDPlayerPath\adbOut1.txt -RedirectStandardError $global:LDPlayerPath\adbOut2.txt + $dumpOutput = adb -s $instanceIP shell uiautomator dump 2> $null + #$dumpOutput = (cat $global:LDPlayerPath\adbOut1.txt) + #$dumpError = (cat $global:LDPlayerPath\adbOut2.txt) + logger("saida do commando dump: $dumpOutput") + if(($dumpOutput -Like "*dumped*")) { + logger("Comando 'uiautomator dump' deu successo. Saindo do loop") + break} + if(($cnt -gt 12) -and !($dumpOutput)){ + logger("too many retries, going ahead anyway and breaking loop") + break + } + $instanceIP | Out-File -FilePath "C:\Ldplayer\Ldplayer9\restartADB.txt" 2>$null + logger("deu kill-server, pois deu erro o dump") + adb start-server *> $null + $cnt1=0 + while($true){ + if($cnt1 -gt 10){logger("breaking connect loop since retries exceeded");break} + $connected = adb connect $instanceIP 2>$null + logger("$connected") + $isOnline = adb devices 2> $null + $pattern = [regex]::Escape($instanceIP) + ':\d+\s+device' + if($isOnline -match $pattern){ + break + }else{ + logger("falhou, tenando connectar de novo") + $instanceIP | Out-File -FilePath "C:\Ldplayer\Ldplayer9\restartADB.txt" 2>$null + Start-Sleep -Milliseconds 1000 + } + $cnt1+=1 + } + logger("deu connect") + $cnt+=1 + } + if ($dumpOutput -match 'dumped to: (/[\w/.-]+\.xml)') { + $dumpPath = $Matches[1].Trim() + $fileName = $dumpPath.Split('/')[2] + } else { + logger("Não foi possível encontrar o caminho do dump XML. Tentando novamente...") + Start-Sleep -Seconds 1; continue + } + if (Test-Path ".\$fileName") { Remove-Item ".\$fileName" } + $fileNameLocal = "C:\LDPlayer\LDPlayer9\screen.xml" + logger("começando baixar o arquivo $fileName") + while($true){ + $fetchXML=adb -s $instanceIP pull $dumpPath $fileNameLocal 2>$null + logger($fetchXML) + if($fetchXML -notLike "*1 file pulled*"){logger("error found");continue}else{logger("sucess");break} + logger("done") + } + if ((Test-Path "$fileNameLocal") -and (Get-Item "$fileNameLocal").Length -gt 0) { + $xmlContent = Get-Content -Raw -Path $fileNameLocal -Encoding UTF8 + return + +<#return [PSCustomObject]@{ + Xml = [xml]$xmlContent + Hash = (Get-FileHash -Algorithm MD5 -InputStream ([System.IO.MemoryStream]::new([System.Text.Encoding]::UTF8.GetBytes($xmlContent)))).Hash + }#> + + } + } catch { logger("Exceção na tentativa $attempt. $_"); + Start-Sleep -Seconds 1 + } + } + logger("Falha crítica ao capturar a UI após 3 tentativas.") + return $null +} +adb connect $instanceIP *> $null + +Get-ScreenData +Handle-SystemDialogs \ No newline at end of file diff --git a/waitUntilThisAppears.ps1 b/waitUntilThisAppears.ps1 new file mode 100644 index 0000000..53c6375 --- /dev/null +++ b/waitUntilThisAppears.ps1 @@ -0,0 +1,256 @@ +param ( + [Parameter(Mandatory=$true)] + [string]$operator, + + [Parameter(Mandatory=$false)] + [string]$timeout, + + [Parameter(Mandatory=$false)] + [string[]]$repeatActions, + + [Parameter(Mandatory=$false)] + [int]$repetitions, + + [Parameter(Mandatory=$false)] + [string]$actionArgs, + + [Parameter(Mandatory=$false)] + [string]$instanceIP, + + [Parameter(Mandatory=$true)] + [string[]]$conditions +) +if(-not $instanceIP){$instanceIP = "10.0.211.121"} + +$global:LDPlayerPath ="C:\Ldplayer\LDplayer9" + +function logger($logMessage) { + [int]$number = (get-content -path "$global:LDPlayerPath\index_count.txt") + if($number -gt 21){ $number=0} + $instanceList = Get-Content -Path "$global:LDPlayerPath\instanceList.txt" + $instanceNumber = $instanceList[$number] + $instanceData = (cat C:\Ldplayer\LDplayer9\vms\config\leidian${instanceNumber}.config) + $convertedData = $instanceData | ConvertFrom-Json + $name = $convertedData."statusSettings.playerName" + $count = $number+1 + + $scriptName = Split-Path -Leaf $PSCommandPath + $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss.fff" + $timestampedLogMessage = $timestamp + "-$name, ($count/22)-$scriptName-PID: ${PID}-:" + $logMessage + $logFilePath = "$global:LDPlayerPath\LDAutoLog.txt" + $fs = New-Object System.IO.FileStream($logFilePath, [System.IO.FileMode]::Append, [System.IO.FileAccess]::Write, [System.IO.FileShare]::Read) + $sw = New-Object System.IO.StreamWriter($fs) + try { + $sw.WriteLine($timestampedLogMessage) + } finally { + $sw.Close() + $fs.Close() + } + } + + function Fetch-ScreenShot(){ + adb connect $instanceIP *>$null +adb -s $instanceIP exec-out screencap -p > $global:LDPlayerPath\screenshot.png *>$null + + & "C:\Program Files\Tesseract-OCR\tesseract.exe" "$global:LDPlayerPath\screenshot.png" "$global:LDPlayerPath\tesseract" -l eng tsv *>$null +} + +function Get-ScreenshotData($text) { + + + + $tsvFile = "$global:LDPlayerPath\tesseract.tsv" + + $wordCoords = Get-Content $tsvFile | ConvertFrom-Csv -Delimiter "`t" + $wordCoords | Where-Object ($_.level -eq 5) | Select-Object text, left, top, width, height + + + $Data = $wordCoords | ForEach-Object { + $x1 =[int]$_._left + $y1 =[int]$_.top + $width = [int]$_.width + $height = [int]$_.height + + $midX =[math]::Round($x1+$width/2) + $midY =[math]::Round($y1+$height/2) + + [PSCustomObject]@{ + Text = $_.text + Coords = "$midX $midY" + } + } + $Element = $Data | Where-Object {$_.Text -and $_.Text.ToLower() -eq $text} + + $coordsForText=$Element.Coords + return $coordsForText +} + +function Get-ScreenData() { + $maxDumpRetries =20 + $dumpRetryCount = 0 + for ($attempt = 1; $attempt -le 3; $attempt++) { + try { + logger("Capturando hierarquia da UI (Tentativa $attempt)...") + Start-Sleep -Milliseconds 250 + + + $cnt = 0 + logger("$dumpOutput") + while($dumpRetryCount -lt $maxDumpRetries){ + if($cnt -gt 50){break} + logger("tentando fazer dump") + + $dumpOutput = adb -s $instanceIP shell uiautomator dump 2> $null + + logger("$dumpOutput é saida do commando dump") + if($dumpOutput -Like "*dumped*") { + logger("Comando 'uiautomator dump' deu successo. Saindo do loop") + break} + tskill adb *> $null + logger("deu kill-server, pois deu erro o dump") + adb start-server *> $null + + while($dumpRetryCount -lt $maxDumpRetries){ + $connected = adb connect $instanceIP 2> $null + logger("$connected") + if($connected -like "*connected*"){break}else{logger"falhou, tenando connectar de novo"} + } + logger("deu connect") + $cnt+=1 + } + if ($dumpOutput -match 'dumped to: (/[\w/.-]+\.xml)') { + $dumpPath = $Matches[1].Trim() + $fileName = $dumpPath.Split('/')[2] + } else { + logger("Não foi possível encontrar o caminho do dump XML. Tentando novamente...") + Start-Sleep -Seconds 1; continue + } + if (Test-Path ".\$fileName") { Remove-Item ".\$fileName" } + $fileNameLocal = "C:\LDPlayer\LDPlayer9\screen.xml" + logger("começando baixar o arquivo $fileName") + while($true){ + $fetchXML=adb -s $instanceIP pull $dumpPath $fileNameLocal 2>null + logger($fetchXML) + if($fetchXML -notLike "*1 file pulled*"){logger("error found");continue}else{logger("sucess");break} + logger("done") + } + if ((Test-Path "$fileNameLocal") -and (Get-Item "$fileNameLocal").Length -gt 0) { + $xmlContent = Get-Content -Raw -Path $fileNameLocal -Encoding UTF8 + return + +<#return [PSCustomObject]@{ + Xml = [xml]$xmlContent + Hash = (Get-FileHash -Algorithm MD5 -InputStream ([System.IO.MemoryStream]::new([System.Text.Encoding]::UTF8.GetBytes($xmlContent)))).Hash + }#> + + } + } catch { logger("Exceção na tentativa $attempt. $_"); + Start-Sleep -Seconds 1 + } + } + logger("Falha crítica ao capturar a UI após 3 tentativas.") + return $null +} +$timeoutSeconds = $timeout +$stopwatch = [System.Diagnostics.Stopwatch]::StartNew() +if($timeout){logger("timetout is $timeoutSeconds") +if($repeatActions){logger("repeat action $repeatActions")}else{logger("no repeat action")} +}else{logger("no timeout")} +$actionCount = $repeatActions.Count +$repetitions +$numberOfRepeats=0 +while($true) { + logger("waiting for condition: $allConditions to appear/disapear") + if($timeoutSeconds -ge 0){ + if($stopwatch.Elapsed.TotalSeconds -ge $timeoutSeconds) { + + if(($repeatActions) -and ($numberOfRepeats -gt $repetitions)) + { + logger("timeout reached, repeating action $repeatActions") + start-sleep -seconds 2 + if($actionArgs -gt 0){ + for($i = 0; $i -lt $actionCount; $i += 2){ + & "$global:LDPlayerPath\actions.ps1" -action $repeatActions[$i], $repeatActions[$i+1] + } + + } else { + for($i = 0; $i -lt $actionCount; $i+= 2){ + & "$global:LDPlayerPath\actions.ps1" -action $repeatActions[$i], $repeatActions[$i+1]} + + } + $stopwatch.Reset() + $numberOfRepeats+=1 + $stopwatch = [System.Diagnostics.Stopwatch]::StartNew() + continue + } else + { + if(!$repeatActions){logger("timeout reached, breaking loop, but no conditions satisfied")} + else {logger("finished repeating $repetions times, but no conditions satisfied, so breaking loop to avoid AD INFINITUM")} + break + } + } + } +Get-screenData +$xml = (get-content -path C:\LDPlayer\LDPlayer9\screen.xml) + +if (-not $conditions) { return $false } +if (-not $operator) {return $false} + + $allConditions = $conditions + switch ($operator) { + "OR" { + logger("OR operator selected to find any of these: $allConditions") + foreach ($condition in $allConditions) { if ($xml | select-string $condition) { + $textInfo = (Get-Culture).TextInfo + $titleCaseString = $textInfo.ToTitleCase($condition) + $conditionMet = $titleCaseString -replace '\s', '' + logger("$conditionMet") + logger("CONDITION MET, BREAKING LOOP and stopping wait") + return $conditionMet + } + } + logger("condition NOT met YET, continuing loop") + continue + } + "AND" { + $allMet = $true + foreach ($condition in $allConditions) { if (-not ($xml | select-string $condition)) { + $allMet = $false + break + } + } + if($allMet){ + return $true + } + continue + } + "NAND" { + logger("NAND operator selected to return true if any one of these are NOT present: $allConditions") + + foreach ($condition in $allConditions) { + if (-not ($xml | select-string $condition)) { + logger("at least $condition is dissapeared, so returning TRUE and breaking wait loop since NAND operator was specified") + return $true + } + } + logger("All conditions are present, so continuing wait loop since NAND operator was specified") + continue + } + "NOR" { + logger("NOR operator selected to return TRUE only when all of the conditions are absent: $allConditions") + $allAbsent = $true + foreach($condition in $allConditions){ + if($xml | Select-String $condition) { + $allAbsent =$false + logger("$condition is present so continuing wait loop since all have to be absent") + break + } + } + if($allAbsent){ + logger("None of the conditions are present so returning TRUE and breaking wait loop (since neither this NOR that condition was present");return $true + } + } + } + +Start-Sleep -Milliseconds 500 +} diff --git a/whatsappSendMessage.ps1 b/whatsappSendMessage.ps1 new file mode 100644 index 0000000..ae0d36c --- /dev/null +++ b/whatsappSendMessage.ps1 @@ -0,0 +1 @@ +"adb -s 10.0.211.121 shell am start -a android.intent.action.VIEW -d 'https://api.whatsapp.com/send?phone=+5511945369906'; ping 127.0.0.1 -n 3 > nul; adb -s 10.0.211.121 shell input text "teste"; ping 127.0.0.1 -n 1 > nul; adb -s 10.0.211.121 shell input keyevent 22; adb -s 10.0.211.121 shell input keyevent 22; ping 127.0.0.1 -n 1 > nul; adb -s 10.0.211.121 shell input keyevent 22; adb -s 10.0.211.121 shell input keyevent 22" \ No newline at end of file