Что нового

Прогресс бар для Copy /b

gora

Знающий
Сообщения
315
Репутация
19
Решил добавить прогресс бар для операции Copy /b. Написал тестовый скрипт:
Код:
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

$archive = 'x:\bigArch\Office2003__.7z' ; > 1 ГБ 
$module = 'x:\bigArch\7zsd_LZMA2.sfx' ; ~ 100 КБ
$config = 'x:\bigArch\_Для_скриншотов.txt' ; ~ 10 КБ

$sfx = 'x:\bigArch\Office2003.exe'

FileDelete($sfx)

_Copy_b($module, $config, $archive)
Exit

Func _Copy_b($c1, $c2, $c3)
	$allSize = FileGetSize($c1) + FileGetSize($c2) + FileGetSize($c3)
	Run(@ComSpec & ' /c Copy /b "' & $c1 & '" + "' & $c2 & '" + "' & $c3 & '" "' & $sfx & '"', '', @SW_HIDE)
	GUICreate("Запись на диск " & $allSize & ' байт', 205, 67, 5, 5, $WS_BORDER)
	$hProgress = GUICtrlCreateProgress(10, 10, 180, 20)
	GUISetState(@SW_SHOW)

	While 1
		$size = FileGetSize($sfx)
		If $size = $allSize Then ExitLoop
		$persent =  Round($size * 100 / $allSize)
		GUICtrlSetData($hProgress, $persent)
		Sleep(10)
	WEnd
GUIDelete()
EndFunc	;==> _Copy_b()

Но индикатор прогресса ведет себя очень странно. Немного подвинется и стоит пока файл не создастся полностью и скрипт не закроется.
Если при работе скрипта открыть папку с создаваемым файлом в ТС и нажимать клавишу F2 (Обновить) в ТС, то видно, что размер файла растет и при этом прогресс тоже движется в такт с этими нажатиями.
Видимо FileGetSize не может считать размер у растущего файла без посторонних обращений к этому файлу.
Как заставить нормально работать скрипт?
 

Medic84

Омега
Команда форума
Администратор
Сообщения
1,583
Репутация
335
gora
Попробовать следить за увеличением размера папки, а не файла?
 
Автор
G

gora

Знающий
Сообщения
315
Репутация
19
Medic84
Это не удобно.
1 Папка может быть очень большая и надо будет считать ее размер при запуске. (потеря времени)
2 Нет гарантий, что пользователь или система не изменит содержание папки за время создания файла и тогда скрипт либо зависнет, либо выйдет из цикла досрочно.

ps
Проверил вариант с папкой - тоже самое.
 

Medic84

Омега
Команда форума
Администратор
Сообщения
1,583
Репутация
335
madmasles
Ему нужно обязательно через CMD - потому что copy \b собирает файлы в 1
 
Автор
G

gora

Знающий
Сообщения
315
Репутация
19
Проблема не имеет решения??? :-\
 
Автор
G

gora

Знающий
Сообщения
315
Репутация
19
madmasles
Это муляж, он не покажет истинного хода процесса. :(
Может есть способ как-то "дергать" создаваемый файл, дабы система выдавала истинный текущий размер для FileGetSize ?
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,320
gora,
У меня приемлимо работают оба варианта.
Код:
$iSizeNow = 0
$sFile1 = @ScriptDir & '\123.7z';469 МБ
$sFile2 = @ScriptDir & '\123.txt'
$sFile3 = @ScriptDir & '\123.sfx'
$sFileExe = @ScriptDir & '\123.exe'

$iSize1 = FileGetSize($sFile1)
$iSize2 = FileGetSize($sFile2)
$iSize3 = FileGetSize($sFile3)
FileDelete($sFileExe)

ProgressOn('Test', 'Test', '0.00%', 50, 50, 16)
$iSizeAll = $iSize1 + $iSize2 + $iSize3
Run(@ComSpec & ' /C Copy /b "' & $sFile1 & '" + "' & $sFile2 & '" + "' & $sFile3 & '" "' & $sFileExe & '"', @SystemDir, @SW_HIDE)
While $iSizeNow < $iSizeAll
	$iSizeNow = FileGetSize($sFileExe)
	$iPersent = 100 * $iSizeNow / $iSizeAll
	ProgressSet(Round($iPersent), StringFormat('%.2f%', $iPersent))
	Sleep(50)
WEnd
MsgBox(64, 'Info', 'All')
ProgressOff()

Код:
#include <GuiConstantsEx.au3>
#include <ProgressConstants.au3>
#include <SendMessage.au3>
#include <StaticConstants.au3>

$iSizeNow = 0
$sFile1 = @ScriptDir & '\123.7z';469 МБ
$sFile2 = @ScriptDir & '\123.txt'
$sFile3 = @ScriptDir & '\123.sfx'
$sFileExe = @ScriptDir & '\123.exe'

$iSize1 = FileGetSize($sFile1)
$iSize2 = FileGetSize($sFile2)
$iSize3 = FileGetSize($sFile3)
$iSizeAll = $iSize1 + $iSize2 + $iSize3

$hGUI = GUICreate('Test', 300, 120)
$nProgress = GUICtrlCreateProgress(0, 100, 300, 20, $PBS_SMOOTH)
GUICtrlSetState($nProgress, $GUI_HIDE)
$hProgress = GUICtrlGetHandle($nProgress)
$nLabel = GUICtrlCreateLabel('', 10, 20, 280, 20, $SS_CENTER)
$nButton = GUICtrlCreateButton('Click', 100, 40, 100, 30)
GUISetState()
While 1
	Switch GUIGetMsg()
		Case $GUI_EVENT_CLOSE
			Exit
		Case $nButton
			FileDelete($sFileExe)
			$iSizeNow = 0
			GUICtrlSetStyle($nProgress, $PBS_MARQUEE)
			_SendMessage($hProgress, $PBM_SETMARQUEE, True, 100)
			GUICtrlSetState($nProgress, $GUI_SHOW)
			Run(@ComSpec & ' /C Copy /b "' & $sFile1 & '" + "' & $sFile2 & '" + "' & $sFile3 & '" "' & $sFileExe & '"', @SystemDir, @SW_HIDE)
			While $iSizeNow < $iSizeAll
				$iSizeNow = FileGetSize($sFileExe)
				;$iPersent = 100 * $iSizeNow / $iSizeAll
				;GUICtrlSetData($nLabel, StringFormat('%.2f% [%.2f mb] (%.2f mb)', $iPersent, $iSizeNow / 1048576, $iSizeAll / 1048576))
				GUICtrlSetData($nLabel, StringFormat('[%.2f mb] (%.2f mb)', $iSizeNow / 1048576, $iSizeAll / 1048576))
				Sleep(100)
			WEnd
			_SendMessage($hProgress, $PBM_SETMARQUEE, False)
			GUICtrlSetStyle($nProgress, $PBS_SMOOTH)
			GUICtrlSetState($nProgress, $GUI_HIDE)
			GUICtrlSetData($nProgress, 0)
			MsgBox(64, 'Info', 'All', 0, $hGUI)
	EndSwitch
WEnd
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,320
gora,
Проверил на Win XP 32 (слабый ноутбук), Win 7 32 и Win 7 64, v.3.3.6.1.

На XP первый варианта: 0% - 7% - 15% - 23%, далее нормально.
На обеих Win 7 первый вариант 0% - 95% - 100%, мне не понравилось, второй нормально, прогресс шевелится, размер растет, правда очень быстро (и на XP так же).
На XP еще на v.3.3.8.0 проверял - тоже нормально.
 
Автор
G

gora

Знающий
Сообщения
315
Репутация
19
madmasles
Провел ряд тестов.
1 Откатил AutoIt до 3.3.6.1 - результатов нет.
2 Перенес файл скрипта в папку с тестовыми файлами (до этого он у меня был на флешке) - результат частичный. Т.е. при размере 0.7 ГБ "размер" немного движется, а после увеличения размера архива до 1.3 ГБ снова перестало работать.
3 Перенес всю папку на другой дисковод (на котором стоит система, до этого папка была на втором дисководе). - результата нет.
4 Менял размеры архива от 0.4 до 1.3 ГБ - иногда как-то работает, но нормального хода нет. Все какие-то зависания да скачки. А на размере 0.4 ГБ после клика по кнопке в окне даже не обнуляются показания.
В ходе тестов обязательно должны быть закрыты все окна с тестовой папкой и ТС, т.к., система иногда сама обновляет информацию в них.
 
Верх