Показать полную графическую версию : [решено] Мне необходим бат таймер
vlad_exe@vk
11-05-2012, 19:56
Мне необходим батник который будет считать время которое он запущен и сохранять значение в конфигурационный файл cfg.cfg . После при следующим запуске будет показывать прежние время работы батника и общее время рыботы батника в целом , все значения должны сохраняться в конфиг , и после нажатия любой клавишы начинать новый щот .
Пожалуйста помогите оч нужно для школы ))) .
Anonymоus
11-05-2012, 20:53
начинать новый щот »
Чего-чего начинать? Простите, но на этом форуме призывы к написанию постов грамотным русским языком содержатся даже в правилах (http://forum.oszone.net/rules.html), пункт 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
За неграмотность извините я просто быстро набирал и как то само ((( , а со скриптом мягко говоря сложновато , если бы пример или готовый скрипт ((( .
Anonymоus
12-05-2012, 07:21
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
::========================================================================
Anonymоus, попробовал ради интереса.
:: Задержка между обновлениями данных
:: Возможно, слишком маленькая. Если скрипт излишне нагружает процессор,
:: стоит сделать её меньше
:: Замечу, что срабатывание выхода по нажатию кнопки тоже зависит от
:: этого таймаута
Ping -n 2 127.0.0.1>nul
Может сделать "дольше" имелось ввиду?
при 1 загрузка ~30 процентов, при 2 обычная и исчезла "рваная" прорисовка как при 1
Anonymоus
12-05-2012, 11:13
yurfed, да, вы правы, опечатался.
vlad_exe@vk
12-05-2012, 11:29
ХаХ красота СПС Всем )))
vlad_exe@vk
12-05-2012, 11:49
Это мне не д/з мы программирование ещё не изучаем , это для души :)
vlad_exe@vk
12-05-2012, 12:18
Нашелся какой то баг , иногда запуская скрипт сразу 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
vlad_exe@vk, погонял скрипт подольше, и верно, может такое случаться. Добавил установку переменных в нули в начале DeserializeTime. Раньше не замечал, в моих скриптах эти функции по другому вызываются.
vlad_exe@vk
12-05-2012, 14:20
...
vlad_exe@vk
26-06-2012, 20:07
А можно сделать чтобы вся инфа сохранялся отдельно вот в таком виде .
LastSession.txt
00:00:19
TotalTime.txt
00:00:24
TotalDays.txt
0
P. S. необходимо для подгрузки на сайт
Anonymоus
27-06-2012, 07:27
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
::=====================================================================
выделено жирным: »
Дополнительно выделяйте цветом. Будет заметнее.
vlad_exe@vk
03-11-2012, 14:33
Возникла необходимость конвертнуть батника в .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
Всё нашел способ сам обойтись без
:: Запуск второй копии внутри первой
:: (для организации примитивного управления вторым запущенным процессом)
If "%SelfStart%"=="" (
Set SelfStart=yes
Start /B "" "%~nx0"
GoTo ControlThread
)
и
:: Создание файла завершения работы по нажатию любой кнопки
:ControlThread
Pause>nul
Echo.>"%temp%\stop.flag"
Exit
спасибо за код! немного переделать осталось. у меня немного другой случай, то что нужно в title это дело выводить, вместе с другими параметрами кое-чего, т.к. в самом терминале будут логи одной проги.
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.