Global Const $STD_INPUT_HANDLE = -10
Global Const $STD_OUTPUT_HANDLE = -11
Global Const $STD_ERROR_HANDLE = -12
Global Const $INVALID_HANDLE_VALUE = -1
Global Const $_CONSOLE_SCREEN_BUFFER_INFO = "short dwSizeX; short dwSizeY;short dwCursorPositionX; short dwCursorPositionY; short wAttributes;short Left; short Top; short Right; short Bottom; short dwMaximumWindowSizeX; short dwMaximumWindowSizeY"
Global Const $_COORD = "short X; short Y"
Global Const $_CHAR_INFO = "wchar UnicodeChar; short Attributes"
Global Const $_SMALL_RECT = "short Left; short Top; short Right; short Bottom"
Global Const $K32 = "Kernel32.dll", $INT = "int", $HWN = "hwnd", $PTR = "ptr", $DWO = "dword"
_7zRead('"f:\Win8.1Upd\DISM8.1\dism_8.1_x32\dism.exe" /Mount-Image /ImageFile:"f:\Win8.1Upd\Wim\boot.wim" /Index:2 /MountDir:f:\Mount')
Func _7zRead($sCmd, $iProgress="", $sProgress="", $sProgressSubText="", $iStatic="", $iStaticText="", $nShow = @SW_HIDE)
$iPID = Run($sCmd, "", $nShow)
ProcessWait($iPID)
If $iStatic Then GUICtrlSetData($iStatic, $iStaticText & "0%")
Local $hPercent = Open7ZipPercent($iPID), $opercent = -1
While ProcessExists($iPID)
Local $nPercent = Read7ZipPercent($hPercent)
If $nPercent >= 0 And $opercent <> $nPercent Then
If $sProgressSubText Then $sProgressSubText = $nPercent
If $sProgress Then ProgressSet($nPercent, $nPercent & "%")
If $iProgress Then GUICtrlSetData($iProgress, $nPercent)
If $iStatic Then GUICtrlSetData($iStatic, $iStaticText & $nPercent & "%")
$opercent = $nPercent
ConsoleWrite($nPercent&@CRLF)
Else
Sleep(50)
EndIf
WEnd
Close7ZipPercent($hPercent)
EndFunc ;==>_7zRead
;internal helper functions ++++++++++++++++++++++++++++++++++++++++++++++++++++
Func Open7ZipPercent($pid)
If _AttachConsole($pid) = 0 Then Return
Local $vHandle[4]
$vHandle[0] = _GetStdHandle($STD_OUTPUT_HANDLE)
$vHandle[1] = DllStructCreate($_CONSOLE_SCREEN_BUFFER_INFO)
$vHandle[2] = DllStructCreate("dword[4]")
$vHandle[3] = DllStructCreate($_SMALL_RECT)
ConsoleWrite($vHandle&@CRLF)
Return $vHandle
EndFunc ;==>Open7ZipPercent
Func Close7ZipPercent(ByRef $vHandle)
If UBound($vHandle) <> 4 Then Return False
DllCall($K32, $INT, "FreeConsole")
$vHandle = 0
Return True
EndFunc ;==>Close7ZipPercent
Func Read7ZipPercent(ByRef $vHandle)
If UBound($vHandle) = 4 Then
Local Const $hStdOut = $vHandle[0]
Local Const $pConsoleScreenBufferInfo = $vHandle[1]
Local Const $pBuffer = $vHandle[2]
Local Const $pSmallRect = $vHandle[3]
If _GetConsoleScreenBufferInfo($hStdOut, $pConsoleScreenBufferInfo) Then
DllStructSetData($pSmallRect, "Left", DllStructGetData($pConsoleScreenBufferInfo, "dwCursorPositionX") - 4)
DllStructSetData($pSmallRect, "Top", DllStructGetData($pConsoleScreenBufferInfo, "dwCursorPositionY"))
DllStructSetData($pSmallRect, "Right", DllStructGetData($pConsoleScreenBufferInfo, "dwCursorPositionX"))
DllStructSetData($pSmallRect, "Bottom", DllStructGetData($pConsoleScreenBufferInfo, "dwCursorPositionY"))
If _ReadConsoleOutput($hStdOut, $pBuffer, $pSmallRect) Then
Local $sPercent = ""
For $i = 0 To 3
Local $pCharInfo = DllStructCreate($_CHAR_INFO, DllStructGetPtr($pBuffer) + ($i * 4))
$sPercent &= DllStructGetData($pCharInfo, "UnicodeChar")
Next
If StringRight($sPercent, 1) = "%" Then Return Number($sPercent)
EndIf
EndIf
EndIf
Return -1
EndFunc ;==>Read7ZipPercent
Func _GetStdHandle($nHandle)
Local $aRet = DllCall($K32, $HWN, "GetStdHandle", $DWO, $nHandle)
If @error Then Return SetError(@error, @extended, $INVALID_HANDLE_VALUE)
ConsoleWrite($aRet[0]&@CRLF)
Return $aRet[0]
EndFunc ;==>_GetStdHandle
Func _AttachConsole($nPid)
Local $aRet = DllCall($K32, $INT, "AttachConsole", $DWO, $nPid)
If @error Then Return SetError(@error, @extended, False)
ConsoleWrite($aRet[0]&@CRLF)
Return $aRet[0]
EndFunc ;==>_AttachConsole
Func _GetConsoleScreenBufferInfo($hConsoleOutput, $pConsoleScreenBufferInfo)
Local $aRet = DllCall($K32, $INT, "GetConsoleScreenBufferInfo", $HWN, $hConsoleOutput, $PTR, _SafeGetPtr($pConsoleScreenBufferInfo))
If @error Then Return SetError(@error, @extended, False)
ConsoleWrite($aRet[0]&@CRLF)
Return $aRet[0]
EndFunc ;==>_GetConsoleScreenBufferInfo
Func _ReadConsoleOutput($hConsoleOutput, $pBuffer, $pSmallRect);, 65540, 0,
Local $aRet = DllCall($K32, $INT, "ReadConsoleOutputW", $PTR, $hConsoleOutput, $INT, _SafeGetPtr($pBuffer), $INT, 65540, $INT, 0, $PTR, _SafeGetPtr($pSmallRect))
If @error Then SetError(@error, @extended, False)
ConsoleWrite($aRet[0]&@CRLF)
Return $aRet[0]
EndFunc ;==>_ReadConsoleOutput
Func _SafeGetPtr(Const ByRef $PTR)
Local $_ptr = DllStructGetPtr($PTR)
If @error Then $_ptr = $PTR
ConsoleWrite($_ptr&@CRLF)
Return $_ptr
EndFunc ;==>_SafeGetPtr