На главную
ПРАВИЛА FAQ Помощь Участники Календарь Избранное DigiMania RSS
msm.ru
Модераторы: Jin X
  
> Трюки в CMD, интересные процедуры...
    Проверку поддержки расширенной обработки команд и включение этой расширенной обработки, а также отложенного расширения переменных среды я делаю следующим образом:
    ExpandedWrap disabled
      if [%cmdextversion%] == [] goto nocmdext
      if not cmdextversion 1 goto nocmdext
      setlocal EnableExtensions EnableDelayedExpansion
      if errorlevel 1 goto nocmdext
    Не уверен, что это наиболее оптимальный вариант (вероятно, он избыточен), предложите свой :)


    Вывод сообщений с обрамлением чёрточками (символ # заменяется на !):
    ExpandedWrap disabled
      @echo off
      setlocal EnableExtensions EnableDelayedExpansion
       
      echo.
      call :ShowMsg "Hello, my friend#"
      exit /b
       
      :ShowMsg str(#=!)
      set _s=%~1&call :StrLen !_s!&call :StrRep !_l! -
      echo %_s:#=^^!%
      call :StrRep %_l% -
      exit /b
      :StrLen str
      set _=%*&set _l=0&(for /l %%i in (1,1,256) do if #!_! neq # set /a _l+=1&set _=!_:~0,-1!)&exit /b
      :StrRep count str
      set _=&(for /l %%i in (1,1,%1) do set _=!_!%2)&echo !_!&exit /b
    p.s. Кол-во чёрточек ограничено 256 символами (для упрощения).
    Есть и более сложные (быстрые и универсальные) процедуры вычисления длины строки.


    Вывод сообщений без перевода строки и задержка (демонстрация вентилятора):
    ExpandedWrap disabled
      @echo off
      setlocal EnableExtensions EnableDelayedExpansion
       
      for /l %%i in (1,1,10) do (
        call :Write "|◘"
        call :Delay 10
        call :Write /◘
        call :Delay 10
        call :Write -◘
        call :Delay 10
        call :Write \◘
        call :Delay 10
      )
      exit /b
       
      :Write str
      set /p=%1<nul
      exit /b
       
      :Delay hundredth
      call :GetTicks _a
      :_WaitDelay
      call :GetTicks _b
      set /a _b=_b-_a
      if %_b% lss 0 set /a _b+=8640000
      if %_b% lss %~1 goto _WaitDelay
      exit /b
       
      :GetTicks var
      set _t=%time: =0%
      set /a %1=1%_t:~9,2%-100+(1%_t:~6,2%-100)*100+(1%_t:~3,2%-100)*6000+(1%_t:~0,2%-100)*360000
      exit /b
    Не потеряйте здесь символы с кодом 8 !!! (◘)
    p.s. Суть вывода сообщений без перевода строки сводится к одной простой команде:
    ExpandedWrap disabled
      set /p=Строка<nul
    или так:
    ExpandedWrap disabled
      <nul set /p=Строка


    Ещё один пример с задержкой (определение прошедшего времени):
    ExpandedWrap disabled
      @echo off
      setlocal EnableExtensions EnableDelayedExpansion
       
      echo.
      echo Подождите, команда выполняется...
      call :GetTicks tick1
       
      :: Выполняем команду
      dir c:\ /s > nul
       
      call :GetTicks tick2
      set /a hs=%tick2%-%tick1%
      if %hs% lss 0 set /a hs+=8640000
      set /a h=%hs%/360000
      set /a m=(%hs%/6000)%%60
      set /a s=(%hs%/100)%%60
      set /a hs=%hs%%%100
      echo Прошедшее время: %h% час %m% мин %s%.%hs% сек.
      pause
      exit /b
       
      :GetTicks var
      set _t=%time: =0%
      set /a %1=1%_t:~9,2%-100+(1%_t:~6,2%-100)*100+(1%_t:~3,2%-100)*6000+(1%_t:~0,2%-100)*360000
      exit /b


    Чтение ini-файлов:
    ExpandedWrap disabled
      @ECHO OFF
      :: Check Windows version
      IF NOT "%OS%"=="Windows_NT" GOTO Syntax
      :: Check command line
      ECHO.%1 | FIND "?" >NUL
      IF NOT ERRORLEVEL 1 GOTO Syntax
      IF [%3]==[] GOTO Syntax
      :: Check if INI file exists
      IF NOT EXIST "%~f1" GOTO Syntax
       
      :: Keep variables local and enable delayed variable expansion
      SETLOCAL ENABLEDELAYEDEXPANSION
       
      :: Read variables from command line
      SET INIFile="%~f1"
      SET INISection=%~2
      SET INIKey=%~3
      SET INIValue=
       
      :: Reset temporary variables
      SET SectOK=0
      SET SectFound=0
      SET KeyFound=0
       
      :: Search the INI file line by line
      FOR /F "tokens=* delims=" %%A IN ('TYPE %INIFile%') DO CALL :ParseINI "%%A"
       
      :: Display the result
      ECHO.
      :: EXIT /B return codes (errorlevels) added by Van Woods,
      :: US Army Corps of Engineers, Seattle District
      IF NOT %SectFound%==1 (
          ECHO INI section not found
          EXIT /B 1
      ) ELSE (
          IF NOT %KeyFound%==1 (
              ECHO INI key not found
              EXIT /B 2
          ) ELSE (
              IF DEFINED INIValue (
                  ECHO.%INIFile%
                  ECHO [%INISection%]
                  ECHO %INIKey%=%INIValue%
              ) ELSE (
                  ECHO Value not defined
                  EXIT /B 3
              )
          )
      )
       
      :: Corrected environment variable by Van Woods,
      :: US Army Corps of Engineers, Seattle District
      ENDLOCAL & SET %INIKey%=%INIValue%
      GOTO:EOF
       
       
      :ParseINI
      :: Skip rest of file after key has been found;
      :: speed improvement by Jeroen Verschuuren
      IF "%SectFound%"=="1" IF "%KeyFound%"=="1" GOTO:EOF
      :: Store quoted line in variable
      SET Line="%~1"
       
      :: Check if this line is the required section heading
      ECHO.%Line%| FIND /I "[%INISection%]" >NUL
      IF NOT ERRORLEVEL 1 (
          SET SectOK=1
          SET SectFound=1
          GOTO:EOF
      )
      :: Check if this line is a different section header
      IF "%Line:~1,1%"=="[" SET SectOK=0
      IF %SectOK%==0 GOTO:EOF
       
      :: Parse any "key=value" line
      FOR /F "tokens=1* delims==" %%a IN ('ECHO.%Line%') DO (
          SET Key=%%a^"
          SET Value=^"%%b
      )
       
      :: Strip quotes, tabs, and surrounding spaces from key and value
      :: Modifications added by Van Woods,
      :: US Army Corps of Engineers, Seattle District
      SET Value=%Value:"=%
      :: Remove quotes
      SET Key=%Key:"=%
      :: Remove tabs
      SET Value=%Value:   =%
      SET Key=%Key:   =%
      :: Remove leading spaces
      FOR /F "tokens=* delims= " %%A IN ("%Key%")   DO SET Key=%%A
      FOR /F "tokens=* delims= " %%A IN ("%Value%") DO SET Value=%%A
      :: Remove trailing spaces
      FOR /L %%A in (1,1,32) do if "!Key:~-1!"==" " set Key=!Key:~0,-1!
      FOR /L %%A in (1,1,32) do if "!Value:~-1!"==" " set Value=!Value:~0,-1!
       
      :: Now check if the key matches the required key
      IF /I "%Key%"=="%INIKey%" (
          SET INIValue=%Value%
          SET KeyFound=1
      )
       
      :: End of ParseINI subroutine
      GOTO:EOF
       
       
       
      :Syntax
      ECHO.
      ECHO ReadINI.bat,  Version 1.30 for Windows NT 4 / 2000 / XP / Server 2003
      ECHO Read a value from the specified INI file
      ECHO.
      ECHO Usage:  READINI  "ini_file"  "section"  "key"
      ECHO Where:           "ini_file" is the file name of the INI file to be read
      ECHO                  "section"  is the section name, without the brackets
      ECHO                  "key"      is the key whose value must be read
      ECHO.
      ECHO Example: if MYPROG.INI looks like this:
      ECHO     [Section 1]
      ECHO     Key1=Value 1
      ECHO     Key2=Value 2
      ECHO     [Section 2]
      ECHO     Key2=Value 4
      ECHO Then the command:  READINI "MYPROG.INI" "section 1" "key2"
      ECHO will return:       Key2=Value 2
      ECHO.
      ECHO Written by Rob van der Woude
      ECHO http://www.robvanderwoude.com
      ECHO Speed improvement by Jeroen Verschuuren
      ECHO Return codes, whitespace removal and corrected environment variable
      ECHO by Van Woods, US Army Corps of Engineers, Seattle District


    Добавляйте и вы что-нибудь интересное! ;)
    vpmultishiftqb vscatterpf0dps vfmsubadd132pd vgatherpf1dps vpclmulhqlqdq vcmptrue_ussd vaeskeygenassist
      Цитата Jin X @
      Ещё один пример с задержкой

      Задержку по фэншую (в венде) задают в виде пинга в n-повторений.
      Мои программные ништякиhttp://majestio.info
        Цитата JoeUser @
        Задержку по фэншую (в венде) задают в виде пинга в n-повторений.
        Так?
        ExpandedWrap disabled
          ping 127.0.0.1 -n 5 -w 0 > nul
        Вариант, конечно, но только если нужна задержка, кратная 1 секунде.
        В моём примере точность 10 мс (1/100 сек).
        vpmultishiftqb vscatterpf0dps vfmsubadd132pd vgatherpf1dps vpclmulhqlqdq vcmptrue_ussd vaeskeygenassist
          Цитата Jin X @
          Так?

          Ну да, как-то так
          Мои программные ништякиhttp://majestio.info
            M

            Продолжение обсуждения задержки и PowerShell вырублено в отдельную тему:
            Задержка
            vpmultishiftqb vscatterpf0dps vfmsubadd132pd vgatherpf1dps vpclmulhqlqdq vcmptrue_ussd vaeskeygenassist
            0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
            0 пользователей:


            Рейтинг@Mail.ru
            [ Script Execution time: 0,1232 ]   [ 18 queries used ]   [ Generated: 18.12.18, 23:33 GMT ]