Вот эта картинка создана .bat файлом:
Многие не знают, но если приложить немного усилий, то командный процессор MS Windows становится способен на многое. В принципе, это обычный императивный язык программирования, немного со странностями, но именно они превращают программирование на нём в своеобразное развлечение. Многие действия, не предусмотренные в конструкции языка, надо придумать как имитировать, порой какими-то фантастическими способами.
Например, как сделать паузу на заданное количество секунд? Команда pause тут бессильна. В место неё паузу удобно организовать через ping.
Пауза на 5 секунд будет выглядеть вот так:
Вот как узнать, содержит ли строка подстроку? Опять же, на первый взгляд ничего подходящего нет. На помощь приходит замена подстроки в строке:
Ещё на .bat можно организовать вычисления с плавающей точкой (изначально плавающая точка не поддерживается), распараллеленные вычисления, синхронизацию между «процессами», распараллеленное вычисление на нескольких компьютерах и т.п. Я как-то раз видел исходники полиморфного(!) вируса, который полностью написан на bat-файле :)
В общем, время от времени я пишу что-нибудь на .bat, не могу пройти мимо такого вызова :)
Cейчас выкладываю одну из своих работ: батник, который рендерит множество Мандельброта в bmp.
Многие не знают, но если приложить немного усилий, то командный процессор MS Windows становится способен на многое. В принципе, это обычный императивный язык программирования, немного со странностями, но именно они превращают программирование на нём в своеобразное развлечение. Многие действия, не предусмотренные в конструкции языка, надо придумать как имитировать, порой какими-то фантастическими способами.
Например, как сделать паузу на заданное количество секунд? Команда pause тут бессильна. В место неё паузу удобно организовать через ping.
Пауза на 5 секунд будет выглядеть вот так:
ping 127.0.0.1 -n 6 -w 1000 > nul
Вот как узнать, содержит ли строка подстроку? Опять же, на первый взгляд ничего подходящего нет. На помощь приходит замена подстроки в строке:
set string=SOME TEXT
if not "%string%"=="%string:TEXT=%" echo YES
Ещё на .bat можно организовать вычисления с плавающей точкой (изначально плавающая точка не поддерживается), распараллеленные вычисления, синхронизацию между «процессами», распараллеленное вычисление на нескольких компьютерах и т.п. Я как-то раз видел исходники полиморфного(!) вируса, который полностью написан на bat-файле :)
В общем, время от времени я пишу что-нибудь на .bat, не могу пройти мимо такого вызова :)
Cейчас выкладываю одну из своих работ: батник, который рендерит множество Мандельброта в bmp.
@echo off
set /a xPixels = 180
set /a yPixels = 120
set /a xStart = -22000
set /a yStart = -10000
set /a xSize = 32000
set /a ySize = 20000
set /a maxIter = 32
call ::make_bmp_header
set /a xStep = xSize/xPixels
set /a yStep = ySize/yPixels
set /a iy = 0
:iyLoop
set /a ix = 0
:ixLoop
set /a x = xStart + ix * xStep
set /a y = yStart + iy * yStep
set /a x0 = x
set /a y0 = y
set /a iteration = 0
:formula
set /a xtemp = x*x/10000 - y*y/10000 + x0
set /a y = 2*x*y/10000 + y0
set /a x = xtemp
set /a iteration+=1
set /a dist = x*x/10000 + y*y/10000
if [%iteration%]==[%maxIter%] goto breakFormula
if /I %dist% LEQ 40000 goto :formula
:breakFormula
if [%iteration%]==[%maxIter%] (call :plot_black) else (call :plot_color %iteration%)
set /a ix += 1
if not [%ix%]==[%xPixels%] goto ixLoop
set /a progress = yPixels - iy
echo.%progress%
set /a iy += 1
if not [%iy%]==[%yPixels%] goto iyLoop
call ::make_bin
ren file$ result.bmp
mspaint result.bmp
exit/b
:plot_black
call :write_byte 0
call :write_byte 0
call :write_byte 0
exit/b
:plot_color
set /a rc=%1*5 + 32
set /a gc=%1*7 + 6
set /a bc=128 - (%1*3 + 4)
call :write_byte %rc%
call :write_byte %gc%
call :write_byte %bc%
exit/b
:make_bmp_header
set /a dataSize = xPixels * yPixels * 3 + 54
set /a dataSize0 = dataSize%%256
set /a dataSize1 = (dataSize/256)%%256
set /a dataSize2 = (dataSize/(256*256))%%256
set /a dataSize3 = (dataSize/(256*256*256))%%256
call :init_bin
call :write_byte 66
call :write_byte 77
call :write_byte 118
call :write_byte 56
call :write_byte 0
call :write_byte 0
call :write_byte 0
call :write_byte 0
call :write_byte 0
call :write_byte 0
call :write_byte 54
call :write_byte 0
call :write_byte 0
call :write_byte 0
call :write_byte 40
call :write_byte 0
call :write_byte 0
call :write_byte 0
call :write_byte %xPixels%
call :write_byte 0
call :write_byte 0
call :write_byte 0
call :write_byte %yPixels%
call :write_byte 0
call :write_byte 0
call :write_byte 0
call :write_byte 1
call :write_byte 0
call :write_byte 24
call :write_byte 0
call :write_byte 0
call :write_byte 0
call :write_byte 0
call :write_byte 0
call :write_byte %dataSize0%
call :write_byte %dataSize1%
call :write_byte %dataSize2%
call :write_byte %dataSize3%
call :write_byte 0
call :write_byte 0
call :write_byte 0
call :write_byte 0
call :write_byte 0
call :write_byte 0
call :write_byte 0
call :write_byte 0
call :write_byte 0
call :write_byte 0
call :write_byte 0
call :write_byte 0
call :write_byte 0
call :write_byte 0
call :write_byte 0
call :write_byte 0
exit /b
:init_bin
echo.n file$>bin$
set /a addr=0x0100
call set "hstr=e "
call :write_word %addr%
set mustflush=0
exit /b
:write_byte
set /a a=%1
set hexs=0123456789ABCDEF
set /a a0=a/16
set /a a1=a%%16
call set res= %%hexs:~%a0%,1%%%%hexs:~%a1%,1%%
set hstr=%hstr%%res%
set /a addr+=1
set /a mod16=addr%%16
set mustflush=1
if not %mod16%==0 exit /b
echo.%hstr%>>bin$
call set "hstr=e "
call :write_word %addr%
set mustflush=0
exit /b
:write_word
set /a a=%1
set hexs=0123456789ABCDEF
set /a a0=a/4096
set /a a1=a/256%%16
set /a a2=a/16%%16
set /a a3=a%%16
call set res=%%hexs:~%a0%,1%%%%hexs:~%a1%,1%%%%hexs:~%a2%,1%%%%hexs:~%a3%,1%%
set hstr=%hstr%%res%
exit /b
:make_bin
if "%mustflush%"=="1" echo.%hstr%>>bin$
set /a filesz=addr-0x0100
echo.r cx>>bin$
set hstr=
call :write_word %filesz%
echo %hstr%>>bin$
echo.w>>bin$
echo.q>>bin$
debug<bin$
del bin$
exit /b