Форум программистов, компьютерный форум, киберфорум
Наши страницы
Batch (CMD/BAT)
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.64/648: Рейтинг темы: голосов - 648, средняя оценка - 4.64
Dragokas
Эксперт WindowsАвтор FAQ
16945 / 7030 / 855
Регистрация: 25.12.2011
Сообщений: 10,832
Записей в блоге: 16
#1

Тонкости языка, редкие команды и сложные скрипты

16.10.2012, 06:56. Просмотров 129745. Ответов 94

Тема для пользователей высокого уровня подготовки.

Здесь можете размещать:
  • Ваши статьи;
  • Ссылки на другие статьи (допускаются статьи на английском языке);
  • Редкие ошибки, выдаваемые интерпретатором, способы их устранения/либо причины возникновения.
  • Недокументированные и особые трюки работы с файловой системой, устройствами и т.п.
  • Разрешено обсуждение выложенных здесь материалов (в последствии будут выделены в отдельную тему);
  • Запрещено обсуждение новичками проблем работы с CMD, где вероятная причина - банальная синтаксическая ошибка.


Статьи и тонкости языка:
Основы
  • FAQ по файлам BAT/CMD (статья) ссылка
  • Командная строка Windows (статья) ссылка
  • Особенности реализации командного процессора cmd.exe операционных систем WinNT (статья) сайт
  • Циклические операции и примеры (статья) эта тема
  • Принцип составления однострочных команд Batch (статья) эта тема
Автозапуск
  • Запуск Bat-файла как службы Эта тема
  • Выполнение командного файла перед входом в систему Эта тема
Безопасность и права
  • Элевация прав запуска BAT-файла (отображается диалог контроля учетных записей UAC) ссылка
  • Как запустить командную строку от имени администратора. эта тема
Интерфейс
  • Переключение языка вывода команд консоли на английский ссылка
КомментарийМатематика
  • Деление с выводом дробной части на батниках ссылка
  • Деление через строковую математику (для делимого, превышающего тип данных signed long int) ссылка
  • Получение 16-ричного представления числа эта тема
  • Получение кода символа по таблице ASCII из числового значения byte эта тема
  • Перевод чисел из десятеричной системы в любую (2-16) эта тема
  • Логические операции сравнения для чисел, превышающих арифметику CMD эта тема
Операционная система, реестр
  • Почему нежелательно запускать BAT из 32-битной среды в 64-разрядной системе. ссылка
  • Функции чтения/записи ключа реестра с отображением уровня ошибки ссылка
Переменные и аргументы
  • Подстановка значения переменной в имя или параметр другой переменной эта тема
  • Перебросить значение через локаль эта тема
  • Часто задаваемые вопросы по использованию аргументов командной строки (статья) сайт
  • Получение рабочего каталога на определенном диске эта тема
  • Undocumented Dynamic variables (недокументированные способы раскрытия переменных среды) эта тема
ПотокиПроцессы
  • Получение PID, имени, пути и параметров запуска процесса эта тема
Связь с другими языками программирования и средами, комбинированные батники

  • -- JScript
  • Скомбинированный файл CMD + JS (WSH) эта тема
  • Выполнение JS кода через mshta.exe эта тема
    -- VBScript
  • Передача значения из BAT-сценария в VBS-скрипт эта тема
  • Метод возврата значения из VBS-скрипта в BAT-сценарий эта тема
  • Получение ErrorLevel из команды CMD в переменную VBS-скрипта тема
    -- Реестровый ключ
  • Способ хранения ключа реестра внутри бат-файла эта тема
    -- Ресурсы внутри BAT-файла
  • Распаковка текстовой информации, заданной меткой в файле CMD, во внешний файл тема
  • Встраивание ресурсов в БАТ-файл тема
    -- Другое:
  • Комбинированный файл CMD + KIXTART
  • Объектно-ориентированное программирование на bat ссылка
Текстовые операции и работа с "массивами"
  • Вывод текста без переноса на новую строку (статья) эта тема
  • Чтение текста из файла без пропуска пустых строк эта тема
  • Экранировать восклицательный знак эта тема
  • Получить последний токен в заданной строке эта тема
  • Урезать в строке справа лишние пробелы или другие подряд идущие символы эта тема
  • Получение символов BackSpace (0x08) и Esc (0x27) в переменную эта тема
  • Функция для работы с массивами эта тема
  • Считывание файла в псевдомассив с учетом пустых строк эта тема
  • Функция правильного выравнивания текста по знакам табуляции эта тема
  • Способ передачи в бат-файл параметра содержащего символы & и последующей обработки полученного значения эта тема
Циклы
  • Подстановка переменной в роле модификатора для цикла эта тема
  • Разбиение строки на токены, если разделитель - кавычка эта тема
Файловые операции
  • Объединить 2 файла (сохранив результаты в одном из них) эта тема
  • Получение информации о размере папки эта тема

References, Special Manuals, Книги для High Level Users:
  • Command-line Reference (Microsoft Tech-Net)
  • Недокументированные и малоизвестные возможности Windows XP (книга)
  • Описание встроенных консольных утилит и команд для различных версий ОС dx21.com CMD-Reference

Баги интерпретатора CMD и встроенных команд
Планируется разместить:
Rem не всегда является командой начала комментария
Создание и удаление точек повторной обработки сайт
.

Если у Вас возникли вопросы, создайте новую тему.
16
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
16.10.2012, 06:56
Ответы с готовыми решениями:

После выполнения определённой команды не выполняются последующие команды
Объясните, пожалуйста, почему может останавливаться выполнение второй и далее...

Тонкости языка С,define
Здравствуйте. Разбираюсь с одной либой для hd44780, есть вопрос по поводу...

Поддерживает ли встроенный сервер PHP скрипты языка Perl?
В PHP существует встроенный сервер. Создаю файл index.html с формой и файл...

создать програму которая содержит в себе команды обработки строк языка асемблер
Создать програму которая содержит в себе команды обработки строк языка...

Как скрипты видят другие скрипты, которые были объявлены ранее?
Может кто-нибудь объяснить как реализовано то, что у нас скрипт, который был...

94
Dragokas
Эксперт WindowsАвтор FAQ
16945 / 7030 / 855
Регистрация: 25.12.2011
Сообщений: 10,832
Записей в блоге: 16
25.03.2013, 03:42  [ТС] #21
Получить последний токен в заданной строке.
(подпрограмма)
%1 - значение строки
%2 - разделитель в кавычках
%3 - переменная-буфер
Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
::Получает значение последнего токена в строке, отделенного в тексте указанным разделителем
::Имеет преимущество перед другими парсерами:
:: - разделителями могут быть некоторые спецсимволы, например знак "=";
:: - количество токенов неограничено.
:GetLastToken %1-in.String %2-in.Delimiter %3-out.Last.Token.Variable
Set "%~3="
Set "_String=%~1"
Set _nLastDelim=-1
for /L %%C in (0,1,8184) do (
  if "!_String:~%%C,1!"=="" Goto ex_GetLastToken
  if "!_String:~%%C,1!"=="%~2" Set _nLastDelim=%%C
)
:ex_GetLastToken
Set /A _nLastDelim+=1
Set "%~3=!_String:~%_nLastDelim%!"
Exit /B
Более простой вариант:
Bash
1
2
3
4
5
@echo off
set st=C:\Users\Fire\Desktop\Личный кабинет абонента.url
set "st="%st:\=" "%""
for %%a in (%st%) do set st=%%~a
echo %st%
Урезать в строке справа лишние пробелы или другие подряд идущие символы
(подпрограмма)
%1 - значение строки
%2 - символ (например, пробел, окруженный кавычками)
%3 - переменная-буфер
Bash
1
2
3
4
5
6
7
8
9
10
11
::Удаляет справа лишние пробелы, или другие подряд идущие символы, заданные переменной %2 (Symbol)
:RTrimSpaces %1-in.String %2-in.Symbol %3-out.String.Variable
Set "%~3="
Set "_String=%~1"
for /L %%C in (0,1,8184) do (
  if "!_String:~%%C,1!"=="" Goto ex_RTrimSpaces
  if "!_String:~%%C,1!"=="%~2" (if not Defined LastSpace (Set nSpace=%%C& Set LastSpace=true)) else (Set LastSpace=& Set nSpace=)
)
:ex_RTrimSpaces
if Defined nSpace (Set "%~3=!_String:~0,%nSpace%!") else (Set "%~3=!_String!")
Exit /B
0
Dragokas
Эксперт WindowsАвтор FAQ
16945 / 7030 / 855
Регистрация: 25.12.2011
Сообщений: 10,832
Записей в блоге: 16
07.04.2013, 18:44  [ТС] #22
Получение символов BackSpace (0x08) и Esc (0x27) в переменную
Автор: jeb (dostips.com)
(немного подредактировано мной)
Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
:BL.String.CreateDEL_ESC
@echo off
:: Creates two variables with one character DEL=Ascii-08 and ESC=Ascii-27
:: DEL and ESC can be used  with and without DelayedExpansion
setlocal
for /F "tokens=1,2 delims=#" %%a in ('"prompt #$H#$E# & echo on & for %%A in (1) do rem"') do (
  rem ENDLOCAL
  set "DEL=%%a"
  rem set "DEL=%DEL:~0,1%
  set "ESC=%%b"
  goto ext
)
:ext
<nul set /p test=Tes_
<nul set /p test=%DEL%
echo t
0
Eva Rosalene
T for Trans-
4050 / 1589 / 302
Регистрация: 06.01.2013
Сообщений: 4,179
Завершенные тесты: 2
17.04.2013, 22:13 #23
Перевод чисел из десятеричной системы в любую (2-16)

Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
@echo off
::Первый параметр - число в десятичное системе счисления.
::Второй параметр - основание выходной системы счисления (от 2 до 16)
setlocal enabledelayedexpansion
chcp 1251>nul
set dec=%~1
if not "%~2"=="" (set osn=%~2) else (set osn=2)
if !dec! LSS 0 (set /a dec=0 - !dec!&set mn=1)
set tempr=!dec!
set bin=
set H=set HEX.
!H!10=A&!H!11=B&!H!12=C&!H!13=D&!H!14=E&!H!15=F
if !osn! GTR 16 (echo.Слишком большое основание. Максимум 16&exit /b)
if !osn! LSS 2 (echo.Слишком маленькое основание. Минимум 2&exit /b)
:again
 if !tempr! LSS 2 (goto :out)
 set /a tbin=!tempr! %% !osn!
 set /a tmchs=!tempr! - !tbin!
 set /a tempr=!tmchs! / !osn!
 if !tbin! GEQ 10 (set tbin=!HEX.%tbin%!)
 set bin=!tbin!!bin!
goto :again
:out
if "!bin!"=="" (set bin=0)
if not !tempr!==0 (set bin=!tempr!!bin!)
if "!mn!"=="1" (set bin=-!bin!)
echo.!bin!
endlocal&exit /b
1
Smitis
1629 / 338 / 39
Регистрация: 15.10.2012
Сообщений: 529
01.05.2013, 01:52 #24
Уточнение 3961893
Цитата Сообщение от Dragokas Посмотреть сообщение
В конец результирующего файла помещает управляющий символ (&1A) вместо переноса каретки
Есть ключи /a и /b для копирования, соответственно, текстовых и бинарных файлов. При копировании с ключом /a в конец результирующего файла всегда добавляется символ с кодом &1A (это управляющий символ EOT - End Of Text). Кроме того, текстовые файлы будут обрезаны до символа EOT, если он в них встретится. Бинарные файлы копируются "as is". Без ключей /a и /b команда copy включает некий AI, пытаясь определить текстовый файл или бинарный. Результаты этого AI не всегда адекватны. Поэтому, хорошей привычкой может быть всегда использовать ключ /b, даже при копировании текстовых файлов (дабы избежать появление последнего "мусорного" символа).
2
Eva Rosalene
T for Trans-
4050 / 1589 / 302
Регистрация: 06.01.2013
Сообщений: 4,179
Завершенные тесты: 2
22.06.2013, 20:26 #25
Считывание файла в псевдомассив с учетом пустых строк

Bash
1
2
3
4
:ReadTo
for /f "usebackq tokens=*" %%A IN (`find /C /V ""^<"%~1"`) DO (set %~3=%%A)
(for /L %%A IN (1,1,!%~3!) DO (set %~2.%%A=&set /p %~2.%%A=))<"%~1"
exit /b
Синтаксис:
Bash
1
Call :ReadTo <имя файла> <имя псевдомассива> <имя переменной с количеством строк>
Пример использования:
Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@echo off
setlocal enabledelayedexpansion
(echo.1
echo.2
echo.
echo.
echo.""
echo.x)>file.txt
call :ReadTo file.txt string counter
for /L %%A IN (1,1,%counter%) DO (echo.!string.%%A!)
pause>nul
exit /b
 
:ReadTo
for /f "usebackq tokens=*" %%A IN (`find /C /V ""^<"%~1"`) DO (set %~3=%%A)
(for /L %%A IN (1,1,!%~3!) DO (set %~2.%%A=&set /p %~2.%%A=))<"%~1"
exit /b
Несуществующие строки обнуляют переменную. Использовать с осторожностью.
0
Dragokas
Эксперт WindowsАвтор FAQ
16945 / 7030 / 855
Регистрация: 25.12.2011
Сообщений: 10,832
Записей в блоге: 16
22.06.2013, 21:28  [ТС] #26
Цитата Сообщение от FraidZZ Посмотреть сообщение
Bash
1
(for /L %%A IN (1,1,!%~3!) DO (set %~2.%%A=&set /p %~2.%%A=))<"%~1"
Смысл в том, что в каждую итерацию цикла попадает 1 строка, не более.
Т.е. можно и так:
Bash
1
(for /L %%A IN (1,1,!%~3!) DO set /p %~2.%%A=)<"%~1"
0
Eva Rosalene
T for Trans-
4050 / 1589 / 302
Регистрация: 06.01.2013
Сообщений: 4,179
Завершенные тесты: 2
22.06.2013, 21:34 #27
Есди ты использовал эту функцию два раза, с одним и тем же именем переменной, но пустая строка во втором совпадает с непустой в первом - твой вариант перенесет туда обрывок первого файла. А мой сначала обнулит (нет ключа /р, это просто обнуление)

 Комментарий модератора 
Ясно. Спасибо. Часть дискуссии была здесь: Как в текстовом файле удалить все строки, начиная с первой, до строки, соответствующей определенному значению?
0
Dragokas
Эксперт WindowsАвтор FAQ
16945 / 7030 / 855
Регистрация: 25.12.2011
Сообщений: 10,832
Записей в блоге: 16
24.06.2013, 20:27  [ТС] #28
Подстановка переменной в роле модификатора для цикла

На примере получения значений 2-х указанных токенов при парсинге строки:

Bash
1
2
3
4
5
6
7
8
9
10
:split
:: Попарное получение токенов из строки. Номера токенов задаются параметром № 2.
:: %1 - вх. строка
:: %2 - вх. номера токенов
:: %3 - вых.переменная, для хранения 1-го значения
:: %4 - вых.переменная, для хранения 2-го значения
  set "%~3="& set "%~4="
  set g=for /f "tokens=%~2" %%a in ^("%~1"^) do set "%~3=%%a"^& set "%~4=%%b"
  %g%
exit /b
Использование:

Bash
1
2
3
4
5
6
7
8
9
@echo off
::задаем строку 
set st=один два три четыре пять
::получаем 2-е и 3-е слово
call :split "%st%" "2,3" "first" "second"
::выводим на экран
echo Первое слово: %first%
echo Второе слово: %second%
pause& goto :eof
UPD. На самом деле - правильное решение это использовать отложенное раскрытие переменной,
к примеру: tokens=!num!

Еще вариант без отложенного раскрытия от ComSpec: Циклические операции и примеры (команда FOR) * [Статья]
0
Dragokas
Эксперт WindowsАвтор FAQ
16945 / 7030 / 855
Регистрация: 25.12.2011
Сообщений: 10,832
Записей в блоге: 16
24.06.2013, 20:28  [ТС] #29
Логические операции сравнения для чисел, превышающих арифметику CMD

Пример использования:
Bash
1
2
3
4
5
6
7
8
9
10
@echo off
SetLocal EnableExtensions
Call :Logica -2147483648 2147483648 LSS && echo false || echo true
echo errorlevel = %errorlevel%
<nul set /p x=Результат сравнения: 
if "%errorlevel%"=="0" (echo false)
if "%errorlevel%"=="1" (echo true)
if "%errorlevel%"=="2" (echo error)
pause
goto :eof
Функция:

Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
:Logica
:: Логические операции сравнения для чисел, превышающих арифметику CMD
:: Возвращает Errorlevel 1, если true, или 0, если false, 2, если неверно введен параметр
:: %1 - 1-е число
:: %2 - 2-е число
:: %3 - Логическая операция.
:: Допустимые операции:
:: LSS - меньше
:: lEQ - меньше или равно
:: GTR - больше
:: GEQ - больше или равно
  set operation=%~3
  set numb1=%~1
  set numb2=%~2
  ::Удаляем знаки +
  if "%numb1:~0,1%"=="+" set numb1=%numb1:~1%
  if "%numb2:~0,1%"=="+" set numb2=%numb2:~1%
  ::Проверка на равенство
  if "%numb1%"=="%numb2%" (
    if /i "%operation%"=="lEQ" exit /B 1
    if /i "%operation%"=="GEQ" exit /B 1
    if /i "%operation%"=="lSS" exit /B 0
    if /i "%operation%"=="GTR" exit /B 0
  )
  if /i "%operation%"=="lEQ" set operation=LSS
  if /i "%operation%"=="GEQ" set operation=GTR
  ::Если сравниваются отрицательные числа, нужно в конце переворачивать логику
  set inverse=
  if "%numb1:~0,1%"=="-" if "%numb2:~0,1%"=="-" set inverse=true
  ::Проверка на знак
  if "%numb1:~0,1%"=="-" if "%numb2:~0,1%" NEQ "-" (set mean=LSS& goto :ext_Logica)
  if "%numb2:~0,1%"=="-" if "%numb1:~0,1%" NEQ "-" (set mean=GTR& goto :ext_Logica)
  ::Удаляем знаки -
  if "%numb1:~0,1%"=="-" set numb1=%numb1:~1%
  if "%numb2:~0,1%"=="-" set numb2=%numb2:~1%
  :s_Logica
    ::Берем цифры по одному разряду справа
    if "%numb1%"=="" (set r1=) else (set r1=%numb1:~-1%)
    if "%numb2%"=="" (set r2=) else (set r2=%numb2:~-1%)
    if "%r1%"=="" if "%r2%"=="" goto ext_Logica
    if "%r1%"=="" set r1=0
    if "%r2%"=="" set r2=0
    if %r1% NEQ %r2% if %r1% GTR %r2% (set mean=GTR) else (set mean=LSS)
    if "%numb1%" neq "" set numb1=%numb1:~0,-1%
    if "%numb2%" neq "" set numb2=%numb2:~0,-1%
  goto s_Logica
  :ext_Logica
  if defined inverse if "%mean%"=="GTR" (set mean=LSS) else (set mean=GTR)
  if "%operation%"=="GTR" if "%mean%"=="GTR" (exit /B 1) else (exit /B 0)
  if "%operation%"=="LSS" if "%mean%"=="LSS" (exit /B 1) else (exit /B 0)
exit /B 2
2
Dragokas
Эксперт WindowsАвтор FAQ
16945 / 7030 / 855
Регистрация: 25.12.2011
Сообщений: 10,832
Записей в блоге: 16
25.06.2013, 01:57  [ТС] #30
Функция правильного выравнивания текста по знакам табуляции

В связи с тем, что движок форума не поддерживает знак табуляции,
Batch-файл качаем из архива.
3
Миниатюры
Тонкости языка, редкие команды и сложные скрипты  
Вложения
Тип файла: rar Tabs.rar (518 байт, 97 просмотров)
Dragokas
Эксперт WindowsАвтор FAQ
16945 / 7030 / 855
Регистрация: 25.12.2011
Сообщений: 10,832
Записей в блоге: 16
26.06.2013, 10:06  [ТС] #31
Функции чтения/записи реестра с отображением уровня ошибки
-----------------------------------------------------------------------
Функция записи в реестр :Reg_Write
Проверено в Windows 7 и XP. Не требует DelayedExpansion.

Bash
1
2
3
4
5
6
7
:Reg_Write
  :: %1-вх.Ключ
  :: %2-вх.Имя параметра
  :: %3-вх.Тип параметра { REG_SZ, REG_BINARY, REG_DWORD, REG_QWORD, REG_MULTI_SZ, REG_EXPAND_SZ }
  :: %4-вх.Значение
  reg.exe add "%~1" /v "%~2" /t "%~3" /d "%~4" /f
Exit /B %errorlevel%
Пример использования:

Кликните здесь для просмотра всего текста
Bash
1
2
3
4
5
6
7
8
9
10
@echo off
SetLocal EnableExtensions
 
::Запись
Call :Reg_Write "HKCU\Environment" "MyVariable" "REG_SZ" "12345"
echo Функция вернула уровень ошибки: %errorlevel%
echo.
 
pause
goto :eof


Функция :Reg_Read v.1. (Light)
Проверено в Windows 7 и XP. Не требует DelayedExpansion.

Не выводит уровень ошибки.
Неправильно читает значения, если в имени параметра есть пробел.

Bash
1
2
3
4
5
6
7
8
9
10
:Reg_Read
  :: %1-вх.Ключ
  :: %2-вх.Имя параметра
  :: %3-исх.Переменная для хранения значения
  :: %4-исх.(опционально)-Переменная для хранения типа параметра
  set "%~3="& if "%~4" neq "" set "%~4="
  For /f "tokens=2*" %%a In ('Reg.exe query "%~1" /v "%~2"') do (
    set "%~3=%%~b"& if "%~4" neq "" set "%~4=%%~a"
  )
Exit /B
Функция чтения из реестра :Reg_Read v.1. (Standart)
Выводит уровень ошибки.
Неправильно читает значения, если в имени параметра есть пробел.

Bash
1
2
3
4
5
6
7
8
9
10
:Reg_Read
  :: %1-вх.Ключ
  :: %2-вх.Имя параметра
  :: %3-исх.Переменная для хранения значения
  :: %4-исх.(опционально)-Переменная для хранения типа параметра
  set "%~3="& if "%~4" neq "" set "%~4="
  For /f "tokens=1-2*" %%a In ('cmd /e:ON /v:ON /c "Reg.exe query "%~1" /v "%~2"^& echo ^!errorlevel^! err %~2"') do (
    if "%%b"=="err" (set err=%%a) else (set "%~3=%%~c"& if "%~4" neq "" set "%~4=%%~b")
  )
Exit /B %err%
Пример использования:

Кликните здесь для просмотра всего текста
Bash
1
2
3
4
5
6
7
8
9
10
11
12
@echo off
SetLocal EnableExtensions
 
::Чтение
Call :Reg_Read "HKCU\Environment" "Temp" Value KeyType
echo Значение: %Value%
echo Тип ключа: %KeyType%
echo Функция вернула уровень ошибки: %errorlevel%
echo.
 
pause
goto :eof


Функция чтения из реестра :Reg_Read v.2. (Spaces Safety)
Проверено на Windows 7 и XP.
Требует DelayedExpansion.

Кликните здесь для просмотра всего текста
Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
:Reg_Read
  :: %1-вх.Ключ
  :: %2-вх.Имя параметра
  :: %3-исх.Переменная для хранения значения
  :: %4-исх.(опционально)-Переменная для хранения типа параметра
  set "%~3="& if "%~4" neq "" set "%~4="
  For /f "delims=" %%a In ('cmd /e:ON /v:ON /c "Reg.exe query "%~1" /v "%~2"^& echo ^!errorlevel^!"') do (
    set tok_prev=!err!
    set err=%%a
  )
  if "%err%" neq "0" Exit /B %err%
  ::Подсчитываем кол-во токенов в имени параметра, если оно состоит из пробелов
  set "_param=%~2"
  echo %_param% |>nul find " " && (
    set _toks=0
    set "_param="!_param: =" "!""
    for %%a in (%_param%) do set /A _toks+=1
  ) || set _toks=1
  ::Пропускаем полученное кол-во токенов при разборе вывода Reg Query
  set _k_type=& set _k_value=
  :Reg_Read_tok
  for /f "tokens=1*" %%a in ("%tok_prev%") do (
    if !_toks! LEQ 0 (
      if not defined _k_type (
        set "_k_type=%%~a"
      ) else (
        set "_k_value=!_k_value! %%~a"
      )
    )
    set /A _toks-=1
    set "tok_prev=%%b"
    if "%%b" neq "" goto Reg_Read_tok
  )
  set "%~3=%_k_value:~1%"& if "%~4" neq "" set "%~4=%_k_type%")
Exit /B 0


Пример использования:

Кликните здесь для просмотра всего текста
Bash
1
2
3
4
5
6
7
8
9
10
@echo off
SetLocal EnableExtensions EnableDelayedExpansion
 
::Чтение
Call :Reg_Read "HKCU\Environment" "Temp" Value KeyType
echo Значение: %Value%
echo Тип ключа: %KeyType%
echo Функция вернула уровень ошибки: %errorlevel%
echo.
pause
2
Dragokas
Эксперт WindowsАвтор FAQ
16945 / 7030 / 855
Регистрация: 25.12.2011
Сообщений: 10,832
Записей в блоге: 16
06.07.2013, 14:47  [ТС] #32
Способ передачи в бат-файл параметра содержащего символы & и последующей обработки полученного значения
от Elroir

Если передавать параметр в кавычках, то передается полностью. Но вот как дальше работать с этой ссылкой в кавычках...
Передаем батнику ссылку в кавычках и делаем так:
Bash
1
2
3
set test=%1 
set test=%test:&=^&% 
echo %test:~1,-1%
2
Dragokas
Эксперт WindowsАвтор FAQ
16945 / 7030 / 855
Регистрация: 25.12.2011
Сообщений: 10,832
Записей в блоге: 16
06.07.2013, 15:25  [ТС] #33
Запуск Batch-файла как службы

MSDN Создание определяемой пользователем службы через INSTSRV.EXE
Создание службы Windows с помощью программы Sc.exe
MS TechNet Sc create

1) Создание и запуск службы:

Bash
1
2
3
4
5
6
7
8
@echo off
::Путь к запускаемому бату в роле службы
set src=d:\bat.bat
 
sc create My_Service binPath= %windir%\SysWOW64\srvany.exe DisplayName= "My Service"
reg add "HKLM\SYSTEM\CurrentControlSet\Services\My_Service\Parameters" /f /v Application /t REG_SZ /d "%src%"
net start "My_Service"
pause
2) Остановка и удаление службы:

Bash
1
2
3
4
@echo off
net stop "My_Service"
sc delete "My_Service"
pause
Все операции нужно проводить в режиме повышенных прав.

Пример протестирован в Windows 7 x64.
В ОС Windows XP, Vista, 8 файл srvany.exe отсутствует. Перед созданием службы, его следует скопировать в системную папку. 32-битная версия srvany.exe из состава Windows 7 подходит к указанным версиям ОС.
В ОС Windows Vista, 7, 8 служба запускает скрипт на отдельном рабочем столе.

Windows Resource Kit.

Примечание:
Чтобы задать аргументы запуска, нужно создать в разделе My_Service\Parameters ключ:
"AppParameters"="Some Arguments"
Bash
reg add "HKLM\SYSTEM\CurrentControlSet\Services\My_Service\Parameters" /f /v AppParameters /t REG_SZ /d "Some Arguments"
Можно задать рабочий каталог:
"AppDirectory"="C:\Progra~1"
Bash
reg add "HKLM\SYSTEM\CurrentControlSet\Services\My_Service\Parameters" /f /v AppDirectory /t REG_SZ /d "C:\Progra~1"
Важно, пути с пробелами указывать в формате 8.3.
4
Вложения
Тип файла: rar srvany_x32.rar (3.7 Кб, 66 просмотров)
Smitis
1629 / 338 / 39
Регистрация: 15.10.2012
Сообщений: 529
06.07.2013, 23:57 #34
Выполнение командного файла перед входом в систему
Программа старая, но на Window7 32 работает (проверено). Можно назвать аналогом autoexec.bat для NT-систем.
Некоторые замечания:
- Служба запускается до логина пользователя. Соотвественно, имя пользователя в %USERNAME%, пути к папкам, типа %USERPROFILE%, %APPDATA% и т.п. могут быть отличными, от ожидаемых. Лучше всего посмотреть их, записав вывод команды SET в файл (см. пример далее). Соотвественно, права доступа к ресурсам системы надо смотреть для каждого конкретного случая.
- Консольное окно не открывается, соотвественно, никакого вывода, например, через echo, никакой интерактивности, типа pause, не будет (командный файл просто "зависнет" в ожидании ввода). Даже запуская vbs, простейшее окно через msgbox открыть не удаётся. Но можно записывать на диск в файлы. Впрочем, на старых системах что-то может быть по другому.
- После выполнения autoexnt.bat служба останется запущеной, хотя она уже не нужна. Много ресурсов она не потребляет, но её можно остановить прямо там, из autoexnt.bat.
Пример autoexnt.bat:
Bash
1
2
3
4
5
@echo off
echo %date% %time% > c:\autoexnt.log
set >> c:\autoexnt.log
net stop AutoExNT > nul
exit
3
Dragokas
Эксперт WindowsАвтор FAQ
16945 / 7030 / 855
Регистрация: 25.12.2011
Сообщений: 10,832
Записей в блоге: 16
01.08.2013, 15:04  [ТС] #35
Дополнение к коду от m0nkrus и FraidZZ
"Получение N-ной строки из файла"
за авторством aGerman (http://www.dostips.com)

Пример для получения 5-й строки:
Bash
1
2
3
4
5
<test.txt (
  for /l %%i in (1 1 4) do set /p "="
  set /p "st="
)
for /f "tokens=1* delims==" %%i in ("%st%") do set "st=%%j"
2
Charles Kludge
Клюг
7641 / 3156 / 382
Регистрация: 03.05.2011
Сообщений: 8,382
06.08.2013, 21:27 #36
Хитрый SUBST (undoc) - для назначения диска можно использовать не только буквы A-Z, но и цифры 0-9 и символы $,#, :, ! , например:
SUBST $: "%TEMP%
$:

подстановка нe видна ни в эксплорере, ни в ФАРе, ни в самом SUBST'e без параметров, ни по SET . | more. Также работает с шарами Samba на FreeBSD, отмапленными по net use.
5
Dragokas
Эксперт WindowsАвтор FAQ
16945 / 7030 / 855
Регистрация: 25.12.2011
Сообщений: 10,832
Записей в блоге: 16
09.08.2013, 01:41  [ТС] #37
Разбиение строки на токены, если разделитель - кавычка
Автор: amel27

Bash
for /f tokens^=1^,2^,3^ delims^=^" %%a in ("1""2""3") do echo %%a--%%b--%%с
3
Dragokas
Эксперт WindowsАвтор FAQ
16945 / 7030 / 855
Регистрация: 25.12.2011
Сообщений: 10,832
Записей в блоге: 16
11.08.2013, 20:12  [ТС] #38
Как восстановить удаленные файлы и папки из теневых копий в Windows 8
Статья от Вадима Стеркина - ссылка
2
Charles Kludge
Клюг
7641 / 3156 / 382
Регистрация: 03.05.2011
Сообщений: 8,382
21.08.2013, 23:02 #39
Смена даты/времени модификации (modification/last access date/time) на текущую.
Bash
1
copy/b nul >> FILE.EXT+,,
если закрутить в цикл, получим скрипт-аналог touch.exe
Работает на шарах Самбы.
На FAT-разделах меняет только last write date/time, естественно.
5
Dragokas
Эксперт WindowsАвтор FAQ
16945 / 7030 / 855
Регистрация: 25.12.2011
Сообщений: 10,832
Записей в блоге: 16
13.10.2013, 17:54  [ТС] #40
Способ хранения нескольких REG-файлов в теле батника

Используется предварительная распаковка.

Код

Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
@echo off
SetLocal EnableExtensions EnableDelayedExpansion
 
call :RegKeyExecute SetConsoleColor
pause
 
call :RegKeyExecute SetDefaultKeyboardLayout_EN
pause
exit /B
 
 
:RegKeyExecute [Имя ресурса]
  For /F "tokens=1 delims=[]" %%? in ('find /i /n "%~1 begin" ^< "%~f0"') do set LineFrom=%%?& set /A LineFrom+=1
  For /F "tokens=1 delims=[]" %%? in ('find /i /n "%~1 end" ^< "%~f0"') do set LineUntil=%%?& set /A LineUntil-=1
  For /L %%C in (%LineFrom%, 1, %LineUntil%) do set "txtmask=!txtmask!\[%%C\] "
  (for /f "tokens=1* delims=]" %%a in ('find /v /n "" ^<"%~f0"^| findstr /B "%txtmask%" 2^>nul') do Echo=%%b)> "%temp%\my_key.reg"
  REG IMPORT "%temp%\my_key.reg"& >nul del "%temp%\my_key.reg"
Exit /B
 
======================
:SetConsoleColor begin
Windows Registry Editor Version 5.00
 
[HKEY_CURRENT_USER\Console]
"ScreenColors"=dword:0000001a
 
[HKEY_CURRENT_USER\Console\%SystemRoot%_system32_cmd.exe]
"ScreenColors"=dword:0000001a
:SetConsoleColor end
====================
==================================
:SetDefaultKeyboardLayout_EN begin
Windows Registry Editor Version 5.00
 
[HKEY_CURRENT_USER\Keyboard Layout\Preload]
"1"="00000409"
:SetDefaultKeyboardLayout_EN end
================================


Комментарий к коду
Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
@echo off
:: EnableExtensions - Включаем поддержку ключей For /F, For /L
:: EnableDelayedExpansion - Включаем поддержку раскрытия переменных через (!)
SetLocal EnableExtensions EnableDelayedExpansion
 
:: Вызываем функцию RegKeyExecute с аргументом SetConsoleColor
call :RegKeyExecute SetConsoleColor
pause
 
:: Вызываем функцию RegKeyExecute с аргументом SetDefaultKeyboardLayout_EN
call :RegKeyExecute SetDefaultKeyboardLayout_EN
pause
exit /B
 
 
:RegKeyExecute [Имя ресурса]
:: Записывает в переменную LineFrom номер строки, в которой находится текст [Имя ресурса] + ключевое слово "begin", set /A ...+1 начало на одну строку ниже
  For /F "tokens=1 delims=[]" %%? in ('find /i /n "%~1 begin" ^< "%~f0"') do set LineFrom=%%?& set /A LineFrom+=1
:: Записывает в переменную LineUntil номер строки, в которой находится текст [Имя ресурса] + ключевое слово "end", set /A ...-1 конец на одну строку выше
  For /F "tokens=1 delims=[]" %%? in ('find /i /n "%~1 end" ^< "%~f0"') do set LineUntil=%%?& set /A LineUntil-=1
:: Записывает в переменную txtmask номера строк этого файла, где находится читаемый Reg
  For /L %%C in (%LineFrom%, 1, %LineUntil%) do set "txtmask=!txtmask!\[%%C\] "
  (
  :: Нумерует строки всего файла, а потом фильтрует только те, что в переменной txtmask
  for /f "tokens=1* delims=]" %%a in ('find /v /n "" ^<"%~f0"^| findstr /B "%txtmask%" 2^>nul') do Echo=%%b
  :: и записывает текст из этих строк во временную папку, в файл my_key.reg
  )> "%temp%\my_key.reg"
  :: Применяет ключевой файл реестра
  REG IMPORT "%temp%\my_key.reg"& >nul del "%temp%\my_key.reg"
  :: Возвращается в точку вызова подпрограммы
Exit /B
 
:: Просто разделитель для наглядности
======================
:: Здесь пишем произвольное имя, по которому будем идентифицировать + дописываем к нему знак пробела и ключевое слово "begin"
:SetConsoleColor begin
Windows Registry Editor Version 5.00
 
[HKEY_CURRENT_USER\Console]
"ScreenColors"=dword:0000001a
 
[HKEY_CURRENT_USER\Console\%SystemRoot%_system32_cmd.exe]
"ScreenColors"=dword:0000001a
:: в конце делаем тоже самое, но дописываем слово "end"
:SetConsoleColor end
====================
==================================
:SetDefaultKeyboardLayout_EN begin
Windows Registry Editor Version 5.00
 
[HKEY_CURRENT_USER\Keyboard Layout\Preload]
"1"="00000409"
:SetDefaultKeyboardLayout_EN end
================================


Спасибо Koza Nozdri за поднятие вопроса по данной проблеме.
1
13.10.2013, 17:54
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
13.10.2013, 17:54

Редкие программы
тема и тупая, но в институте задали такой вопрос: какие программы считаются...

Lotusscript: редкие конструкции
Здравствуйте, коллеги. Накидайте мне здесь, пожалуйста, хитрых, редких,...

Редкие отключения и сбои ПК
Добрый день! Около 4-ех месяцев назад поменял процессор с i3-3225 на i5-3450...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru