#RequireAdmin #include #include #include #include Global $hGUI = GUICreate("CMD Log par API", 700, 500) Global $inputCmd = GUICtrlCreateInput("ping google.fr", 20, 20, 520, 30) Global $btn = GUICtrlCreateButton("Lancer", 555, 20, 110, 30) Global $bar = GUICtrlCreateProgress(20, 65, 645, 25) Global $lbl = GUICtrlCreateLabel("Prêt.", 20, 100, 645, 20) Global $log = GUICtrlCreateEdit("", 20, 130, 645, 320, _ BitOR($ES_READONLY, $WS_VSCROLL, $ES_AUTOVSCROLL)) GUISetState(@SW_SHOW) While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE Exit Case $btn Local $sUserCmd = StringStripWS(GUICtrlRead($inputCmd), 3) If $sUserCmd = "" Then GUICtrlSetData($lbl, "Commande vide.") ContinueLoop EndIf GUICtrlSetState($btn, $GUI_DISABLE) GUICtrlSetData($bar, 0) GUICtrlSetData($lbl, "Démarrage...") GUICtrlSetData($log, "") _RunHiddenCMD($sUserCmd, $log, $bar, $lbl) GUICtrlSetState($btn, $GUI_ENABLE) EndSwitch WEnd Func _RunHiddenCMD($sUserCmd, $idLog, $idProgress, $idLabel) Local Const $GENERIC_READ = 0x80000000 Local Const $GENERIC_WRITE = 0x40000000 Local Const $FILE_SHARE_READ = 0x00000001 Local Const $FILE_SHARE_WRITE = 0x00000002 Local Const $OPEN_EXISTING = 3 Local $sCmd If @OSArch = "X64" And Not @AutoItX64 Then $sCmd = @WindowsDir & "\Sysnative\cmd.exe" Else $sCmd = @ComSpec EndIf Local $sEndToken = "AUTOIT_CMD_TERMINE_" & @AutoItPID Local $sCommand = '"' & $sCmd & '" /k "' & $sUserCmd & ' & echo. & echo ' & $sEndToken & '"' Local $iPID = Run($sCommand, "", @SW_HIDE) If $iPID = 0 Then GUICtrlSetData($idLabel, "Erreur lancement.") Return False EndIf Sleep(800) DllCall("kernel32.dll", "bool", "FreeConsole") Local $aAttach = DllCall("kernel32.dll", "bool", "AttachConsole", "dword", $iPID) If @error Or Not $aAttach[0] Then GUICtrlSetData($idLabel, "AttachConsole impossible.") Return False EndIf Local $aOpen = DllCall("kernel32.dll", "handle", "CreateFileW", _ "wstr", "CONOUT$", _ "dword", BitOR($GENERIC_READ, $GENERIC_WRITE), _ "dword", BitOR($FILE_SHARE_READ, $FILE_SHARE_WRITE), _ "ptr", 0, _ "dword", $OPEN_EXISTING, _ "dword", 0, _ "ptr", 0) If @error Or $aOpen[0] = Ptr(-1) Then GUICtrlSetData($idLabel, "CONOUT$ inaccessible.") DllCall("kernel32.dll", "bool", "FreeConsole") Return False EndIf Local $hConOut = $aOpen[0] Local $iLastPercent = -1 Local $sLastText = "" While ProcessExists($iPID) Local $tInfo = DllStructCreate( _ "short SizeX;" & _ "short SizeY;" & _ "short CursorX;" & _ "short CursorY;" & _ "ushort Attributes;" & _ "short Left;" & _ "short Top;" & _ "short Right;" & _ "short Bottom;" & _ "short MaxX;" & _ "short MaxY") Local $aInfo = DllCall("kernel32.dll", "bool", "GetConsoleScreenBufferInfo", _ "handle", $hConOut, _ "struct*", $tInfo) If Not @error And $aInfo[0] Then Local $iWidth = DllStructGetData($tInfo, "SizeX") Local $iHeight = DllStructGetData($tInfo, "CursorY") + 1 If $iWidth > 0 And $iHeight > 0 Then Local $iLen = $iWidth * $iHeight Local $tBuffer = DllStructCreate("wchar[" & ($iLen + 1) & "]") Local $tRead = DllStructCreate("dword") Local $aRead = DllCall("kernel32.dll", "bool", "ReadConsoleOutputCharacterW", _ "handle", $hConOut, _ "ptr", DllStructGetPtr($tBuffer), _ "dword", $iLen, _ "dword", 0, _ "ptr", DllStructGetPtr($tRead)) If Not @error And $aRead[0] Then Local $sRaw = DllStructGetData($tBuffer, 1) Local $sText = "" For $i = 1 To StringLen($sRaw) Step $iWidth Local $sLine = StringMid($sRaw, $i, $iWidth) $sLine = StringStripWS($sLine, 2) If $sLine <> "" Then $sText &= $sLine & @CRLF EndIf Next If $sText <> "" And $sText <> $sLastText Then $sLastText = $sText GUICtrlSetData($idLog, $sText) Local $aPercent = StringRegExp($sText, "([0-9]{1,3}(?:\.[0-9]+)?)%", 3) If Not @error Then Local $fPercent = Number($aPercent[UBound($aPercent) - 1]) If $fPercent < 0 Then $fPercent = 0 If $fPercent > 100 Then $fPercent = 100 Local $iPercent = Int($fPercent) If $iPercent <> $iLastPercent Then $iLastPercent = $iPercent GUICtrlSetData($idProgress, $iPercent) GUICtrlSetData($idLabel, "Progression : " & Round($fPercent, 1) & "%") EndIf EndIf If StringInStr($sText, $sEndToken) Then ExitLoop EndIf EndIf EndIf EndIf Sleep(250) WEnd DllCall("kernel32.dll", "bool", "CloseHandle", "handle", $hConOut) DllCall("kernel32.dll", "bool", "FreeConsole") If ProcessExists($iPID) Then ProcessClose($iPID) GUICtrlSetData($idProgress, 100) GUICtrlSetData($idLabel, "Terminé.") Return True EndFunc