Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   [решено] Мне необходим бат таймер (http://forum.oszone.net/showthread.php?t=234460)

vlad_exe@vk 11-05-2012 19:56 1914178

Мне необходим бат таймер
 
Мне необходим батник который будет считать время которое он запущен и сохранять значение в конфигурационный файл cfg.cfg . После при следующим запуске будет показывать прежние время работы батника и общее время рыботы батника в целом , все значения должны сохраняться в конфиг , и после нажатия любой клавишы начинать новый щот .
Пожалуйста помогите оч нужно для школы ))) .

Anonymоus 11-05-2012 20:53 1914200

Цитата:

Цитата vlad_exe@vk
начинать новый щот »

Чего-чего начинать? Простите, но на этом форуме призывы к написанию постов грамотным русским языком содержатся даже в правилах, пункт 2.3

По теме - попробуйте использовать вот эти функции для подсчета времени, вам останется написать лишь чтение\запись настроек, это совсем не сложно, особенно если сделать поиск по форуму. Ну ещё опционально - индикацию самого таймера.

Код:

::===Функции работы со временем в .bat====================================
:: Anonymous, 2010
:ParseTimestamp
:: Разбирает на составляющие временную метку формата ЧЧ:ММ:СС
:: Формат:  Call :ParseTimestamp (время)
:: К примеру - Call :ParseTimestamp %time:~-0,8%
:: Вывод - в переменные HH MM и SS
For /F "tokens=1,2,3 delims=:" %%A In ("%1") Do (
Set HH=%%A
Set MM=%%B
Set SS=%%C
)

:SerializeTime
:: Сериализует время из переменных HH MM и SS
:: Вывод - в ErrorLevel
Set /A STime=(HH*60*60)+(MM*60)+SS
Exit /B %STime%

:DeserializeTime
:: Десериализует время, приводит его к стандартному формату
:: Формат:  Call :DeserializeTime (сериализованное время)
:: Вывод - в переменные DHH DMM и DSS
Set /A DHH=%1/60/60
Set /A DMM=(%1/60)-(DHH*60)
Set /A DSS=%1-(DHH*60*60)-(DMM*60)
If %DHH%==24 Set DHH=00
If %DHH% LSS 10 Set DHH=0%DHH%
If %DMM% LSS 10 Set DMM=0%DMM%
If %DSS% LSS 10 Set DSS=0%DSS%
Exit /B

:TMinus
:: Функция вычитания для сериализованного времени
:: Формат:  Call :TMinus (сериализованное время) (сколько секунд отнять)
:: Вывод - в ErrorLevel
Set /A Result=%1-%2
If %2 GTR %1 (
Set /A Result=86400+%1-%2
)
Exit /B %Result%

:TPlus
:: Функция прибавления для сериализованного времени
:: Формат:  Call :TPlus (сериализованное время) (сколько секунд прибавить)
:: Вывод - в ErrorLevel
Set /A Result=%1+%2
If %Result% GTR 86400 (
Set /A Result=%1+%2-86400
)
Exit /B %Result%

:Timer
:: Отсчитывает прошедшее с заданного момента время
:: Формат:  Call :Timer (запомненное сериализованное время)
:: Вывод - в ErrorLevel
:: Если счетчик переходит границу суток, число дней возрастает на 1
:: Дни выводятся в переменную ED (и накапливаются) // да, знаю, что костыль и быдлокод
Set OTime=%1
If "%ED%"=="" Set ED=0
Call :ParseTimestamp %time:~-0,8%
Call :SerializeTime
Set CTime=%ErrorLevel%
If %OTime% GTR %CTime% (
Set /A Timer=86400-%OTime%+%CTime%
Set /A ED+=1
) Else (
Set /A Timer=CTime-OTime
)
Exit /B %Timer%

:Timer2
:: Проверяет, прошел ли заданный промежуток времени
:: Формат:  Call :Timer2 (запомненное сериализованное время) (промежуток в секундах)
:: Вывод - в ErrorLevel (только 0=промежуток истёк или 1=промежуток ещё не истёк)
Call :ParseTimestamp %time:~-0,8%
Call :SerializeTime
Call :TMinus %ErrorLevel% %1
If %2 GTR %ErrorLevel% Exit /B 1
Exit /B 0
::========================================================================

А насчет события по нажатию кнопки, можете подсмотреть реализацию вот тут:
http://forum.oszone.net/post-1907483-10.html
Только следует заменить ожидание нажатия Enter'а на pause>nul и создание пустого файла, чтобы срабатывало по любой кнопке.

vlad_exe@vk 11-05-2012 23:20 1914266

За неграмотность извините я просто быстро набирал и как то само ((( , а со скриптом мягко говоря сложновато , если бы пример или готовый скрипт ((( .

Anonymоus 12-05-2012 07:21 1914362

vlad_exe@vk, вот готовый скрипт. Но если это для школы, то постарайтесь хотя бы понять логику его работы, чтобы рассказать о ней, когда на уроке информатики или где там это задавали, будут спрашивать. Я бы всё-таки советовал написать самому, используя этот, готовый скрипт в качестве примера, чтобы понять, как он работает.

Код:

@Echo Off
SetLocal EnableDelayedExpansion
If Exist "%temp%\stop.flag" Del "%temp%\stop.flag">nul

:: Запуск второй копии внутри первой
:: (для организации примитивного управления вторым запущенным процессом)
If "%SelfStart%"=="" (
        Set SelfStart=yes
        Start /B "" "%~nx0"
        GoTo ControlThread
)

:WorkThread
:: Назначаем файл настроек
Set CfgFile=config.cfg
:: Проверяем - есть ли файл настроек, если нету - создаем.
If Not Exist "%CfgFile%" (
        >"%CfgFile%" (
                Echo [.cmd timer config file]
                Echo LastSession=00:00:00
                Echo TotalTime=00:00:00
                Echo TotalDays=0
        )
)
:: Читаем файл настроек
Call :ReadKeyValue

:: Начало работы таймера
:: Записываем время начала сессии в переменную
Call :ParseTimestamp %time:~-0,8%
Call :SerializeTime
Set StartedAt=%ErrorLevel%

:Loop
:: Здесь крутится сам таймер
Call :Timer %StartedAt%
Call :DeserializeTime %Timer%
:: Вывод времени на экран
Call :Display
:: Задержка между обновлениями данных
:: Возможно, слишком маленькая. Если скрипт излишне нагружает процессор,
:: стоит сделать её больше.
:: Замечу, что срабатывание выхода по нажатию кнопки тоже зависит от
:: этого таймаута
Ping -n 2 127.0.0.1>nul
:: Тут мы проверяем на сигнал завершения работы, если нету - идем на следующий цикл подсчета
If Exist "%temp%\stop.flag" GoTo Shutdown
GoTo :Loop

:Display
Cls
Echo.
Echo  Timer:          %DHH%:%DMM%:%DSS%
Echo  Last session:  %LastSession%
Echo  Total:  %TotalDays% days  %TotalTime%
Echo.
Echo  Press any key to exit
Exit /B

:Shutdown
:: Обрабатываем время, вычисляя значения и подготавливая их к записи в файл настроек
:: Для удобства чтения человеком сохраняем туда только десериализованное время
Set LastSession=%DHH%:%DMM%:%DSS%
Call :ParseTimestamp %DHH%:%DMM%:%DSS%
Call :SerializeTime
Set SCurrentSession=%STime%
Call :ParseTimestamp %TotalTime%
Call :SerializeTime
Set STotalTime=%STime%
Call :TPlus %SCurrentSession% %STotalTime%
Call :DeserializeTime %Result%
Set TotalTime=%DHH%:%DMM%:%DSS%
Set /A TotalDays=TotalDays+ED
Call :WriteKeyValue
Exit



:: Создание файла завершения работы по нажатию любой кнопки
:ControlThread
Pause>nul
Echo.>"%temp%\stop.flag"
Exit




rem ====== Функции для работы с ini
rem v2, сохраняет комментарии и строки, не являющиеся парой key=value
rem Anonymous, 2011
:ReadKeyValue
If Not Exist %CfgFile% (Exit 1)
Set i=0
For /F "tokens=1,2 delims== usebackq" %%A In ("%CfgFile%") Do (
        Set /A i+=1
        Set %%A=%%B
        Set CfgKey!i!=%%A
        Set CfgStrings=!i!
)
Exit /B

:WriteKeyValue
If Exist "%CfgFile%" (Del "%CfgFile%")
For /L %%S In (1,1,%CfgStrings%) Do (
        Call :SingleLine "!CfgKey%%S!"
)
Exit /B
:SingleLine
If Not "!%~1!"=="" (Echo %~1=!%~1!>>"%CfgFile%") Else (Echo %~1>>"%CfgFile%")
Exit /B
rem ===============================

::===Функции работы со временем в .bat====================================
:: Anonymous, 2010
:ParseTimestamp
:: Разбирает на составляющие временную метку формата ЧЧ:ММ:СС
:: Формат:  Call :ParseTimestamp (время)
:: К примеру - Call :ParseTimestamp %time:~-0,8%
:: Вывод - в переменные HH MM и SS
For /F "tokens=1,2,3 delims=:" %%A In ("%1") Do (
Set HH=%%A
Set MM=%%B
Set SS=%%C
)

:SerializeTime
:: Сериализует время из переменных HH MM и SS
:: Вывод - в ErrorLevel
Set /A STime=(HH*60*60)+(MM*60)+SS
Exit /B %STime%

:DeserializeTime
:: Десериализует время, приводит его к стандартному формату
:: Формат:  Call :DeserializeTime (сериализованное время)
:: Вывод - в переменные DHH DMM и DSS
Set DHH=00&Set DMM=00&Set DSS=00
Set /A DHH=%1/60/60
Set /A DMM=(%1/60)-(DHH*60)
Set /A DSS=%1-(DHH*60*60)-(DMM*60)
If %DHH%==24 Set DHH=00
If %DHH% LSS 10 Set DHH=0%DHH%
If %DMM% LSS 10 Set DMM=0%DMM%
If %DSS% LSS 10 Set DSS=0%DSS%
Exit /B

:TMinus
:: Функция вычитания для сериализованного времени
:: Формат:  Call :TMinus (сериализованное время) (сколько секунд отнять)
:: Вывод - в ErrorLevel
Set Result=
Set /A Result=%1-%2
If %2 GTR %1 (
Set /A Result=86400+%1-%2
)
Exit /B %Result%

:TPlus
:: Функция прибавления для сериализованного времени
:: Формат:  Call :TPlus (сериализованное время) (сколько секунд прибавить)
:: Вывод - в ErrorLevel
Set Result=
Set /A Result=%1+%2
If %Result% GTR 86400 (
Set /A Result=%1+%2-86400
)
Exit /B %Result%

:Timer
:: Отсчитывает прошедшее с заданного момента время
:: Формат:  Call :Timer (запомненное сериализованное время)
:: Вывод - в ErrorLevel
:: Если счетчик переходит границу суток, число дней возрастает на 1
:: Дни выводятся в переменную ED (и накапливаются) // да, знаю, что костыль и быдлокод
Set OTime=%1
If "%ED%"=="" Set ED=0
Call :ParseTimestamp %time:~-0,8%
Call :SerializeTime
Set CTime=%STime%
If %OTime% GTR %CTime% (
Set /A Timer=86400-%OTime%+%CTime%
Set /A ED+=1
) Else (
Set /A Timer=CTime-OTime
)
Exit /B %Timer%

:Timer2
:: Проверяет, прошел ли заданный промежуток времени
:: Формат:  Call :Timer2 (запомненное сериализованное время) (промежуток в секундах)
:: Вывод - в ErrorLevel (только 0=промежуток истёк или 1=промежуток ещё не истёк)
Call :ParseTimestamp %time:~-0,8%
Call :SerializeTime
Call :TMinus %STime% %1
If %2 GTR %Result% Exit /B 1
Exit /B 0
::========================================================================


yurfed 12-05-2012 08:36 1914378

Anonymоus, попробовал ради интереса.
Код:

:: Задержка между обновлениями данных
:: Возможно, слишком маленькая. Если скрипт излишне нагружает процессор,
:: стоит сделать её меньше
:: Замечу, что срабатывание выхода по нажатию кнопки тоже зависит от
:: этого таймаута
Ping -n 2 127.0.0.1>nul

Может сделать "дольше" имелось ввиду?
при 1 загрузка ~30 процентов, при 2 обычная и исчезла "рваная" прорисовка как при 1

Anonymоus 12-05-2012 11:13 1914445

yurfed, да, вы правы, опечатался.

vlad_exe@vk 12-05-2012 11:29 1914458

ХаХ красота СПС Всем )))

vlad_exe@vk 12-05-2012 11:49 1914466

Это мне не д/з мы программирование ещё не изучаем , это для души :)

vlad_exe@vk 12-05-2012 12:18 1914476

Нашелся какой то баг , иногда запуская скрипт сразу Timer: 23:59:59 , config.cfg я не изменял баловался открывал и закрывал Enter`ом и вдруг уже
Timer: 00:00:23
Last session: 23:59:48
Total: 20 days 20:34:00

хотя скрипт за все это время проработал не больше 15 мин :(

Вот удалил конфиг и запустил по открывал по закрывал всегда Enter`ом и вдруг

Timer: 00:01:30
Last session: 00:10:50
Total: 2 days 00:02:28

Как могло пройти 2 дня ((

П.С.
задержку я изменил на yurfed Ping -n 2 127.0.0.1>nul

Может как то задать чтобы Timer: всегда был 00:00:00 может
Код:

@Echo Off
Set DHH=00
Set DMM=00
Set DSS=00

Дописал в начале поможет ли ?

Нет не помогает
Иногда при запуске
Timer: 23:59:59 на пару секунд потом опять 00:00:01 и т.д. и бац уже набросило пару дней , можно как то профиксить


Так попробовал после этого баг вроде бы исчез

Код:

:: Читаем файл настроек
Call :ReadKeyValue

Set DHH=00
Set DMM=00
Set DSS=00

:: Начало работы таймера

Нет нечего не помогло (((

Anonymоus 12-05-2012 13:16 1914520

vlad_exe@vk, погонял скрипт подольше, и верно, может такое случаться. Добавил установку переменных в нули в начале DeserializeTime. Раньше не замечал, в моих скриптах эти функции по другому вызываются.

vlad_exe@vk 12-05-2012 14:20 1914563

...

vlad_exe@vk 26-06-2012 20:07 1940992

А можно сделать чтобы вся инфа сохранялся отдельно вот в таком виде .

LastSession.txt
Код:

00:00:19
TotalTime.txt
Код:

00:00:24
TotalDays.txt
Код:

0
P. S. необходимо для подгрузки на сайт

Anonymоus 27-06-2012 07:27 1941165

vlad_exe@vk, вы это вполне и сами могли сделать - три простейших команды добавить, выделено жирным: (кстати, тут исправлена ошибка с иногда появлявшимися при старте 23.59.59)
Код:

@Echo Off
SetLocal EnableDelayedExpansion
If Exist "%temp%\stop.flag" Del "%temp%\stop.flag">nul

:: Запуск второй копии внутри первой
:: (для организации примитивного управления вторым запущенным процессом)
If "%SelfStart%"=="" (
        Set SelfStart=yes
        Start /B "" "%~nx0"
        GoTo ControlThread
)

:WorkThread
:: Назначаем файл настроек
Set CfgFile=config.cfg
:: Проверяем - есть ли файл настроек, если нету - создаем.
If Not Exist "%CfgFile%" (
        >"%CfgFile%" (
                Echo [.cmd timer config file]
                Echo LastSession=00:00:00
                Echo TotalTime=00:00:00
                Echo TotalDays=0
        )
)
:: Читаем файл настроек
Call :ReadKeyValue

:: Начало работы таймера
:: Записываем время начала сессии в переменную
Call :ParseTimestamp %time:~-0,8%
Call :SerializeTime
Set StartedAt=%ErrorLevel%

:Loop
:: Здесь крутится сам таймер
Call :Timer %StartedAt%
Call :DeserializeTime %Timer%
:: Вывод времени на экран
Call :Display
:: Задержка между обновлениями данных
:: Возможно, слишком маленькая. Если скрипт излишне нагружает процессор,
:: стоит сделать её больше.
:: Замечу, что срабатывание выхода по нажатию кнопки тоже зависит от
:: этого таймаута
Ping -n 2 127.0.0.1>nul
:: Тут мы проверяем на сигнал завершения работы, если нету - идем на следующий цикл подсчета
If Exist "%temp%\stop.flag" GoTo Shutdown
GoTo :Loop

:Display
Cls
Echo.
Echo  Timer:          %DHH%:%DMM%:%DSS%
Echo  Last session:  %LastSession%
Echo  Total:  %TotalDays% days  %TotalTime%
Echo.
Echo  Press any key to exit
Exit /B

:Shutdown
:: Обрабатываем время, вычисляя значения и подготавливая их к записи в файл настроек
:: Для удобства чтения человеком сохраняем туда только десериализованное время
Set LastSession=%DHH%:%DMM%:%DSS%
Call :ParseTimestamp %DHH%:%DMM%:%DSS%
Call :SerializeTime
Set SCurrentSession=%STime%
Call :ParseTimestamp %TotalTime%
Call :SerializeTime
Set STotalTime=%STime%
Call :TPlus %SCurrentSession% %STotalTime%
Call :DeserializeTime %Result%
Set TotalTime=%DHH%:%DMM%:%DSS%
Set /A TotalDays=TotalDays+ED
Call :WriteKeyValue
Echo !LastSession!>LastSession.txt
Echo !TotalTime!>TotalTime.txt
Echo !TotalDays!>TotalDays.txt

Exit



:: Создание файла завершения работы по нажатию любой кнопки
:ControlThread
Pause>nul
Echo.>"%temp%\stop.flag"
Exit




rem ====== Функции для работы с ini
rem v2, сохраняет комментарии и строки, не являющиеся парой key=value
rem Anonymous, 2011
:ReadKeyValue
If Not Exist %CfgFile% (Exit 1)
Set i=0
For /F "tokens=1,2 delims== usebackq" %%A In ("%CfgFile%") Do (
        Set /A i+=1
        Set %%A=%%B
        Set CfgKey!i!=%%A
        Set CfgStrings=!i!
)
Exit /B

:WriteKeyValue
If Exist "%CfgFile%" (Del "%CfgFile%")
For /L %%S In (1,1,%CfgStrings%) Do (
        Call :SingleLine "!CfgKey%%S!"
)
Exit /B
:SingleLine
If Not "!%~1!"=="" (Echo %~1=!%~1!>>"%CfgFile%") Else (Echo %~1>>"%CfgFile%")
Exit /B
rem ===============================

::===Функции работы со временем в .bat====================================
:: Anonymous, 2010
:: v 1.3
:ParseTimestamp
:: Разбирает на составляющие временную метку формата ЧЧ:ММ:СС
:: Формат:  Call :ParseTimestamp (время)
:: К примеру - Call :ParseTimestamp %time:~-0,8%
:: Вывод - в переменные HH MM и SS
For /F "tokens=1,2,3 delims=:" %%A In ("%1") Do (
    Set HH=%%A
    Set MM=%%B
    Set SS=%%C
)

:SerializeTime
:: Сериализует время из переменных HH MM и SS
:: Вывод - в ErrorLevel
Call :Cut %HH% HH&Call :Cut %MM% MM&Call :Cut %SS% SS
Set /A STime=(HH*60*60)+(MM*60)+SS
Exit /B %STime%

:DeserializeTime
:: Десериализует время, приводит его к стандартному формату
:: Формат:  Call :DeserializeTime (сериализованное время)
:: Вывод - в переменные DHH DMM и DSS
Set DHH=00&Set DMM=00&Set DSS=00
Set /A DHH=%1/60/60
Set /A DMM=(%1/60)-(DHH*60)
Set /A DSS=%1-(DHH*60*60)-(DMM*60)
If %DHH%==24 Set DHH=00
If %DHH% LSS 10 Set DHH=0%DHH%
If %DMM% LSS 10 Set DMM=0%DMM%
If %DSS% LSS 10 Set DSS=0%DSS%
Exit /B

:TMinus
:: Функция вычитания для сериализованного времени
:: Формат:  Call :TMinus (сериализованное время) (сколько секунд отнять)
:: Вывод - в ErrorLevel
Set Result=
Set /A Result=%1-%2
If %2 GTR %1 (
    Set /A Result=86400+%1-%2
)
Exit /B %Result%

:TPlus
:: Функция прибавления для сериализованного времени
:: Формат:  Call :TPlus (сериализованное время) (сколько секунд прибавить)
:: Вывод - в ErrorLevel
Set Result=
Set /A Result=%1+%2
If %Result% GTR 86400 (
    Set /A Result=%1+%2-86400
)
Exit /B %Result%

:Timer
:: Отсчитывает прошедшее с заданного момента время
:: Формат:  Call :Timer (запомненное сериализованное время)
:: Вывод - в ErrorLevel
:: Если счетчик переходит границу суток, число дней возрастает на 1
:: Дни выводятся в переменную ED (и накапливаются) // да, знаю, что костыль и быдлокод
Set OTime=%1
If "%ED%"=="" Set ED=0
Call :ParseTimestamp %time:~-0,8%
Call :SerializeTime
Set CTime=%STime%
If %OTime% GTR %CTime% (
    Set /A Timer=86400-%OTime%+%CTime%
    Set /A ED+=1
) Else (
    Set /A Timer=CTime-OTime
)
Exit /B %Timer%

:Timer2
:: Проверяет, прошел ли заданный промежуток времени
:: Формат:  Call :Timer2 (запомненное сериализованное время) (промежуток в секундах)
:: Вывод - в ErrorLevel (только 0=промежуток истёк или 1=промежуток ещё не истёк)
Call :ParseTimestamp %time:~-0,8%
Call :SerializeTime
Call :TMinus %STime% %1
If %2 GTR %Result% Set Timer2=1&Exit /B 1
Set Timer2=0&Exit /B 0

:Cut
:: Убирание ведущих нулей и пробелов
:: Формат:  Call :Cut (Двухзначное число) (Переменная, куда вывести резуьтат)
Set d=%1
If "%d:~,1%"=="0" Set %2=%d:~1%
If "%d:~,1%"==" " Set %2=%d:~1%
Exit /B
::=====================================================================


Iska 27-06-2012 10:53 1941246

Цитата:

Цитата Anonymоus
выделено жирным: »

Дополнительно выделяйте цветом. Будет заметнее.

vlad_exe@vk 03-11-2012 14:33 2017841

Возникла необходимость конвертнуть батника в .exe решил использовать bat to exe converter 1.6 после конвертации он был наречен timer_s.exe и после его первого запуска не захотел работать говорить мол нету timer_s.bat
После небольших изменений

Код:



:: Запуск второй копии внутри первой
:: (для организации примитивного управления вторым запущенным процессом)
If "%SelfStart%"=="" (
        Set SelfStart=yes
        Start /B "" "%~nx0"        на      Start time_s.exe
        GoTo ControlThread
)


Запустился создал файл конфигурации но не захотел после своего открытия обновлять информацию в нём.
Вопрос в том можно ли его заставить работать в .ехе оч надо но именно в ехе ))???
Help !)) Кто-нить ?

vlad_exe@vk 03-11-2012 20:16 2018013

Всё нашел способ сам обойтись без

Код:


:: Запуск второй копии внутри первой
:: (для организации примитивного управления вторым запущенным процессом)
If "%SelfStart%"=="" (
        Set SelfStart=yes
        Start /B "" "%~nx0"
        GoTo ControlThread
)

и

Код:


:: Создание файла завершения работы по нажатию любой кнопки
:ControlThread
Pause>nul
Echo.>"%temp%\stop.flag"
Exit


jeromy1 15-02-2016 15:05 2606290

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


Время: 18:50.

Время: 18:50.
© OSzone.net 2001-