progress bar

Тема в разделе "Пакетные файлы CMD, BAT", создана пользователем alex_diablo, 29 сен 2016.

  1. alex_diablo
    Оффлайн

    alex_diablo Пользователь

    Сообщения:
    104
    Симпатии:
    7
    доброго времени суток! захотелось сделать что-то наподобие прогресс бара во время выполнения батника (установка софта) ...

    на коленке нарисовал такое:

    Код (DOS):
    @echo off

    :begin
    cls
    set "per= ^[^----------^] "
    echo %per%
    timeout /t 2 /nobreak >nul
    if exist c:\temp\unity_log.txt goto exit
    cls
    set "per= ^[^>---------^] "
    echo %per%
    timeout /t 2 /nobreak >nul
    if exist c:\temp\unity_log.txt goto exit
    cls
    set "per= ^[^-^>--------^] "
    echo %per%
    timeout /t 2 /nobreak >nul
    if exist c:\temp\unity_log.txt goto exit
    cls
    set "per= ^[^--^>-------^] "
    echo %per%
    timeout /t 2 /nobreak >nul
    if exist c:\temp\unity_log.txt goto exit
    cls
    set "per= ^[^---^>------^] "
    echo %per%
    timeout /t 2 /nobreak >nul
    if exist c:\temp\unity_log.txt goto exit
    cls
    set "per= ^[^----^>-----^] "
    echo %per%
    timeout /t 2 /nobreak >nul
    if exist c:\temp\unity_log.txt goto exit
    cls
    set "per= ^[^-----^>----^] "
    echo %per%
    timeout /t 2 /nobreak >nul
    if exist c:\temp\unity_log.txt goto exit
    cls
    set "per= ^[^------^>---^] "
    echo %per%
    timeout /t 2 /nobreak >nul
    if exist c:\temp\unity_log.txt goto exit
    cls
    set "per= ^[^-------^>--^] "
    echo %per%
    timeout /t 2 /nobreak >nul
    if exist c:\temp\unity_log.txt goto exit
    cls
    set "per= ^[^--------^>-^] "
    echo %per%
    timeout /t 2 /nobreak >nul
    if exist c:\temp\unity_log.txt goto exit
    cls
    set "per= ^[^---------^>^] "
    echo %per%
    timeout /t 2 /nobreak >nul
    goto begin
    :exit

    exit /b
    даже работает))

    скриптик проверяет появление текстового файла (который должен появиться после завершения установки софта)

    но.. мне бы хотелось поместить прогресс-бар в батник так, чтобы помимо самого прогресс бара еще инфа отображалась для юзеров... типа такого:

    Код (DOS):
    echo.
    echo    Unity installer:
    echo    ================
    echo.
    echo.
    echo    Installation of Unity version %vers% has been started
    echo.
    echo.
    echo.   Please do not close the application before the end of the installation
    echo.
    echo.
    echo.
    echo.
    :: вот куда-нибудь в это место хотелось бы поместить прогресс-бар..
    echo.
    но как это сделать? не перерисовывать же каждый раз полностью все это... иначе простыня получится да и не круто это... можно что-нибудь покрасивше и получше придумать? может с циклами что-то? я мало что в них понимаю...
    буду рад помощи. может кому-то тоже такая штука интересна...
     
  2. Kиpилл
    Оффлайн

    Kиpилл Команда форума Администратор

    Лучший автор месяца

    Сообщения:
    12.219
    Симпатии:
    4.978
    Ну вызовите его через call?
     
  3. alex_diablo
    Оффлайн

    alex_diablo Пользователь

    Сообщения:
    104
    Симпатии:
    7
    покажете как?
     
  4. alex_diablo
    Оффлайн

    alex_diablo Пользователь

    Сообщения:
    104
    Симпатии:
    7
    вроде разобрался.
    --- Объединённое сообщение, 30 сен 2016 ---
    сделал так:

    Код (DOS):
    @ECHO OFF
    SetLocal EnableExtensions

    set num=1

    :begin
    call :progressbar %num%
    cls
    echo.
    echo    Unity installer:
    echo    ================
    echo.
    echo.
    echo    Installation of Unity version %vers% has been started
    echo.
    echo.
    echo.   Please do not close the application before the end of the installation
    echo.
    echo.
    echo.
    echo.  %progressbar%
    timeout /t 1 /nobreak >nul
    if exist c:\temp\unity_log.txt goto exit
    set /a num=%num%+1
    if %num% == 50 set num=1
    goto begin

    :progressbar

    goto progress%1

    :progress1
    set "progressbar= ^[ ---------------------------------------- ^] "
    exit /b

    :progress2
    set "progressbar= ^[ ^>--------------------------------------- ^] "
    exit /b

    :progress3
    set "progressbar= ^[ -^>-------------------------------------- ^] "
    exit /b

    :progress4
    set "progressbar= ^[ --^>------------------------------------- ^] "
    exit /b

    :progress5
    set "progressbar= ^[ ---^>------------------------------------ ^] "
    exit /b

    :progress6
    set "progressbar= ^[ ---^>------------------------------------ ^] "
    exit /b
    :: ...
    :: ...
    :: ...
    :: ...
    :progress50
    set "progressbar= ^[ ---------------------------------------^> ^] "
    exit /b[/code]


    все работает, но слишком уж громоздкий код получается... возможно это как-то попроще сделать и покрасивше? мб через цикл или еще как-то... ?
     
  5. alex_diablo
    Оффлайн

    alex_diablo Пользователь

    Сообщения:
    104
    Симпатии:
    7
    пожалуй, все это не имеет смысла... ибо пока выполняется этот код, другой (в частности основная задача - установка софта) выполняться не будет.. :This:
     
  6. Kиpилл
    Оффлайн

    Kиpилл Команда форума Администратор

    Лучший автор месяца

    Сообщения:
    12.219
    Симпатии:
    4.978
    Так вы параллельно запускайте
     
  7. alex_diablo
    Оффлайн

    alex_diablo Пользователь

    Сообщения:
    104
    Симпатии:
    7
    как это сделать? например, мне нужно сразу 3 вызвать через CALL
     
  8. Dragokas
    Оффлайн

    Dragokas Very kind Developer Команда форума Супер-Модератор Разработчик Клуб переводчиков

    Сообщения:
    4.478
    Симпатии:
    4.307
    Пример:

    Код (DOS):

    @echo off
    SetLocal EnableExtensions

    if "%~1"=="ProgressBar" (call :ProgressBarEx& exit)

    echo.
    echo.
    echo.
    echo My Program
    echo.
    echo Begin LONG LONG operation

    call :ProgressBar Start

    ping 127.1 -n 10

    call :ProgressBar Stop

    echo.
    echo Finished.
    pause>NUL
    goto :eof


    :ProgressBar [Start/Stop]
      if /i "%~1"=="Stop" (del "RegBack.reg"& exit /B)
      >nul reg export "HKCU\Console" RegBack.reg /y
      >nul reg add "HKCU\Console\%%SystemRoot%%_system32_cmd.exe" /v "ScreenBufferSize" /t REG_DWORD /d 0x1001e /f
      >nul reg add "HKCU\Console\%%SystemRoot%%_system32_cmd.exe" /v "WindowSize" /t REG_DWORD /d 0x1001e /f
      start cmd /k "%~f0" ProgressBar
    Exit /B

    :ProgressBarEx
      >nul 2>&1 reg import "RegBack.reg"
      title Ожидайте ...
      For /L %%C in (1,1,2147483647) do (
        ping 127.1 -n 1 >nul
        ping 127.1 -n 1 >nul
        if not exist "RegBack.reg" exit
        set /p="|"<NUL
      )
    exit /B
     
    Screenshot_1.png

    Вместо ping 127.1 -n 10 подставляете полезную нагрузку.
     
    Kиpилл нравится это.
  9. alex_diablo
    Оффлайн

    alex_diablo Пользователь

    Сообщения:
    104
    Симпатии:
    7
    здорово! но хотелось бы обойтись одним окошком...
    --- Объединённое сообщение, 30 сен 2016 ---
    так как запустить параллельно? если я сразу несколько меток, то другие метки не выполняются, пока идет процесс установки...
     
  10. Dragokas
    Оффлайн

    Dragokas Very kind Developer Команда форума Супер-Модератор Разработчик Клуб переводчиков

    Сообщения:
    4.478
    Симпатии:
    4.307
    Не получится. На основании чего Вы будете следить за завершением процесса инсталляции?
     
  11. Kиpилл
    Оффлайн

    Kиpилл Команда форума Администратор

    Лучший автор месяца

    Сообщения:
    12.219
    Симпатии:
    4.978
    Dragokas вам показал,я про то же говорил.
     
  12. Dragokas
    Оффлайн

    Dragokas Very kind Developer Команда форума Супер-Модератор Разработчик Клуб переводчиков

    Сообщения:
    4.478
    Симпатии:
    4.307
    В принципе можно заменить синхронное ожидание процесса на асинхронное, но это будет сильно нагружать ЦП.
    Как вариант, взять в качестве признака проверку на создание какого-то файла, но это будет весьма ненадёжно и не универсально, т.к. в следующей версии установщик например больше не будет создавать отслеживаемый файл и придётся снова корректировать этот скрипт прогрессбара.
     
  13. alex_diablo
    Оффлайн

    alex_diablo Пользователь

    Сообщения:
    104
    Симпатии:
    7
    так я так и сделал. с проверкой на наличие файла. т.е. после отработки основного кода скрипта создается скажем, log.txt
    т.е. файл есть - работу прогресс-бара прекращаем. насчет неуниверсальности - думаю ничего сложного нет сделать при запуске скрипта проверку на наличие этого файла. если есть - прибиваем.
     
  14. Dragokas
    Оффлайн

    Dragokas Very kind Developer Команда форума Супер-Модератор Разработчик Клуб переводчиков

    Сообщения:
    4.478
    Симпатии:
    4.307
    Я думаю, что вы не совсем правильно меня поняли.
    log.txt (или какой-то другой файл) должен создать не ваш скрипт, а установщик*, чтобы служить опознавательным моментом времени того, что он завершил свою работу и можно прекращать крутить по кругу прогрессбар и начать заниматься другими делами.

    * под установщиком подразумевается отдельный процесс, а не какой-нибудь call внутри батника.

    Или как вариант, проверять наличие процесса, но это сожрёт процессорное время.
     
  15. alex_diablo
    Оффлайн

    alex_diablo Пользователь

    Сообщения:
    104
    Симпатии:
    7
    разве нельзя через errorlevel ?
     
  16. Dragokas
    Оффлайн

    Dragokas Very kind Developer Команда форума Супер-Модератор Разработчик Клуб переводчиков

    Сообщения:
    4.478
    Симпатии:
    4.307
    В cmd по errorlevel можно только, если синхронно, только для консольных процессов и только если это предусмотрено разработчиком программы.
    В Вашем случае ничего ничего из этого не будет соблюдено.

    А вообще, да. В WinApi так и делают - смотрят код возврата, имея на руках ProcessID запущенного процесса. Если он = STILL_ALIVE, то процесс ещё жив.
     
    Последнее редактирование: 30 сен 2016
  17. alex_diablo
    Оффлайн

    alex_diablo Пользователь

    Сообщения:
    104
    Симпатии:
    7
    я имел ввиду что-то типа такого:

    Код (Text):
    \\server\Soft\Developers_Tools\Unity\4_5_1\f3\UnitySetup-4.5.1.exe /S /D=C:\Program Files (x86)\Unity_4.5.1
    if %ERRORLEVEL%==1 (echo installation error >c:\temp\unity_error_log.txt) else echo installation finished >c:\temp\unity_log.txt
    т.е. если errorlevel 0 - считаем, что процесс выполнен успешно и создаем соответствующий файл. если 1 - значит ошибка.
    ну а скрипт с прогресс-баром соответственно ждет появления того или другого файла и после их появления прекращает
    крутиться, выводя соответсвующее сообщение: либо успех установки, либо что-то пошло не так.

    т.е. в данном случае любой код возврата означает завершение работы, независимо - успешно или нет. соответственно на основании этого можно создать файл.


    что плохого в данной реализации?
     
    Последнее редактирование: 3 окт 2016
  18. Dragokas
    Оффлайн

    Dragokas Very kind Developer Команда форума Супер-Модератор Разработчик Клуб переводчиков

    Сообщения:
    4.478
    Симпатии:
    4.307
    То, что он не соответствует Вашему требованию, чтобы было не больше 1 окна. Если первое будет ждать завершения процесса, как выполнить код прогрессбара, не имея второго окна (процесса)?
    cmd не поддерживает создание потоков.
     

Поделиться этой страницей