Я предлагаю следующий код пакетного файла для этой задачи:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "HostsFile=%SystemRoot%\System32\drivers\etc\hosts"
if not "%ProgramFiles(x86)%" == "" if exist %SystemRoot%\Sysnative\cmd.exe set "HostsFile=%SystemRoot%\Sysnative\drivers\etc\hosts"
if not exist %HostsFile% goto AppendData
%SystemRoot%\System32\findstr.exe /I /L /C:"foo" %HostsFile% >nul
if not errorlevel 1 goto EndBatch
%SystemRoot%\System32\findstr.exe /R /V "$" %HostsFile% >nul
if not errorlevel 1 echo/>>%HostsFile%
:AppendData
>>%HostsFile% echo 8.8.8.8 foo
:EndBatch
endlocal
Третья строка определяет переменную среды HostsFile
со стандартным путем к файлу, который находится прямо в пакетном файле, выполняемом в 32-битной Windows с помощью32-разрядная cmd.exe
или в 64-разрядной Windows с 64-разрядной cmd.exe
в каталоге %SystemRoot%\System32
.
В четвертой строке учитывается перенаправитель файловой системы Windows в соответствии с Детали реализации WOW64 .Пакетный файл выполняется в 64-битной Windows, если определена переменная среды с именем ProgramFiles(x86)
с непустым значением.Но пакетный файл выполняется 32-битным cmd.exe
в каталоге %SystemRoot%\SysWOW64
, если есть %SystemRoot%\Sysnative\cmd.exe
.Перенаправитель Sysnative
не существует для приложений x64.В этом случае на файл hosts
необходимо ссылаться из 32-битной среды в 64-битной Windows с использованием перенаправителя Sysnative
в пути к файлу.
Далее проверяется, существует ли файл hosts
ввсе.Если файл не существует, добавляемая строка данных может быть напрямую записана в файл без каких-либо дополнительных проверок, в результате чего в этом случае создается файл hosts
.
В противном случае команда FINDSTR используется для поиска без учета регистра с буквально интерпретированной строкой поиска для foo
с перенаправлением, возможно, найденных строк на устройство NUL . FINDSTR завершается со значением 0
, если есть хотя бы одно положительное совпадение, и со значением 1
, если искомая строка не может быть найдена ни в одной строке.
if not errorlevel 1
означает ЕСЛИ код выхода НЕ БОЛЬШЕ ИЛИ РАВНО 1 , или другими словами НИЖЕ, ЧЕМ 1 , или в этом случае РАВНО 0 из-за FINDSTR никогда не завершается с отрицательным значением, как почти все приложения и команды.Таким образом, если это условие истинно, файл hosts
содержит хотя бы один раз искомую строку и ничего не нужно изменять в файле.
В противном случае FINDSTR используется еще раз для поиска в этот раз срегулярное выражение для конца строки и для вывода всех строк не , имеющих конец строки из-за опции /V
.Таким образом, если последняя строка в файле hosts
не имеет конца строки, FINDSTR завершается со значением 0
из-за того, что у нее есть одна строка без конца строки, в результате чего этот вывод перенаправляется на устройство NUL .
Окончание строки добавляется к файлу hosts
, если FINDSTR завершено со значением 0
из-за того, что файл hosts
заканчивается без окончания строки перед добавлением следующей строки данных кДобавить к этому файлу.
Приведенный выше код не работает, если командный файл не выполняется с повышенными разрешениями локального администратора или файл hosts
имеет атрибут только для чтения или защищен от измененияскрипт.
Чтобы понять используемые команды и то, как они работают, откройте окно командной строки, выполните там следующие команды и полностью прочитайте все страницы справки, отображаемые для каждой команды.
echo /?
endlocal /?
findstr /?
goto /?
if /?
set /?
setlocal /?
См. Также тему форума DosTips: ECHO.Не в состоянии дать текст или пустую строку - вместо этого используйте ECHO /