Как я могу использовать файл .bat для удаления определенных токенов из переменной среды PATH?

Я пишу сценарий удаления, поэтому я хотел бы отменить изменения, сделанные при установке системы. В достижении этой цели я бы хотел разобратьПеременная PATH и удалите все значения, добавленные установкой вPATH.

Для этого я разработал следующий псевдокод -

Сохранить содержимоеPATH во временную переменнуюРазделитьPATH в токены, используя; символ в качестве разделителя, и цикл через каждый токен(В цикле) Определите, является ли текущий токен добавленным при установке(В цикле) Если текущий токен не был добавлен установкой, сохраните его для добавления в обновленныйPATH (во временной переменной)Сохранить обновленноеPATH

Я ожидал, что это будет относительно просто реализовать.

Первый шаг, хранениеPATH это просто.

SET TEMP_PATH=%PATH% 

Однако, когда я пытаюсь перебрать каждый токен, он не будет работать так, как я ожидал.

FOR /F "delims=;" %%A IN (%TEMP_PATH%) DO ECHO %%A 

Эта команда выводит только первый токен, и никакие последующие токены не выводятся.

Итак, у меня есть два вопроса -

Как я могу просмотреть неизвестное количество токенов и работать с каждым из них?Есть ли другой способ достичь той же цели, который может быть проще?

Спасибо.

 Klitos Kyriacou29 июл. 2016 г., 15:54
Если вы все еще хотите использовать пакетный файл, используйте команду REG. ТипREG /? за помощью. смотреть наreg query "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" а такжеreg query "HKCU\Environment".
 Klitos Kyriacou29 июл. 2016 г., 13:20
Вам следует подумать об удалении элементов из PATH так же, как они были добавлены. Чтобы увидеть, на что ссылается Эйлид, попробуйте изменить PATH в одном командном окне, затем запустите другое командное окно, и вы увидите, что PATH не изменился.
 Jean-François Fabre29 июл. 2016 г., 12:31
Кажется,% отсутствуют в TEMP_PATH
 Eilidh29 июл. 2016 г., 12:32
@ Jean-FrançoisFabre Извинения, что я копирую код в вопрос, у него есть% в коде. Спасибо. Я обновлю вопрос.
 Eilidh29 июл. 2016 г., 12:38
@ Жан-Франсуа Фабр, не могли бы вы объяснить это поподробнее, пожалуйста?
 Eilidh29 июл. 2016 г., 13:02
Да процесс установки наш, используя.ps1 а также.bat файлы. В рамках этого процесса устанавливаются другие программные зависимости (поэтому мы можем делать такие вещи, как вызовmsiexec удалить их, как вы, возможно, намекаете), но не для всего этого.
 Jean-François Fabre29 июл. 2016 г., 12:36
Проблема с переменной пути заключается в том, что она совпадает между системными и пользовательскими переменными. Если вы сохраните их обратно в реестр, это будет проблемой. Вы должны прочитать пользовательский или системный путь из реестра, а не среды
 Klitos Kyriacou29 июл. 2016 г., 12:48
Некоторые связанные вопросы, чтобы попытаться понять, почему вы делаете это и есть ли лучший способ. Вы также написали сценарий установки в пакетном режиме? Если программное обеспечение поставляется с собственным установщиком, то почему оно не удаляется с помощью аналогичного установщика?

Ответы на вопрос(2)

Эта команда выводит только первый токен, и никакие последующие токены не отображаются.
FOR /F "delims=;" %%A IN (%TEMP_PATH%) DO ECHO %%A 

Как я могу просмотреть неизвестное количество токенов и работать с каждым из них?

Используйте следующий пакетный файл.

SplitPath.cmd:

@echo off
setlocal
for %%a in ("%path:;=";"%") do (
  echo %%~a
  )
endlocal

Пример вывода:

F:\test>path
PATH=C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\apps\WSCC\Sysinternals Suite;C:\apps\WSCC\NirSoft Utilities

F:\test>splitpath
C:\Windows\system32
C:\Windows
C:\Windows\System32\Wbem
C:\Windows\System32\WindowsPowerShell\v1.0\
C:\apps\WSCC\Sysinternals Suite
C:\apps\WSCC\NirSoft Utilities

Заметки:

Изменитьfor цикл в зависимости от ситуации, чтобы реализовать остальную часть вашего псевдокода.Дальнейшее чтениеИндекс A-Z командной строки Windows CMD - Отличный справочник по всем вопросам, связанным с Windows cmd line.за - Условно выполнить команду несколько раз.редактирование / замена переменных - Редактировать и заменять символы, назначенные строковой переменной.
Решение Вопроса

Приведенный ниже пакетный код удаляет 1 или несколько путей к папкам, как определено в верхней части скрипта с помощьюPathToRemove1, PathToRemove2, ... от

пользовательДОРОЖКА текущей учетной записи пользователя, хранящейся в реестре Windows под ключом
HKEY_CURRENT_USER\EnvironmentсистемаДОРОЖКА хранится в реестре Windows под ключом
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment

Обновление системыДОРОЖКА требует прав администратора, что означает, что пакетный файл должен выполняться от имени администратора, если контроль учетных записей пользователей (UAC) не отключен для учетной записи пользователя, выполняющего пакетный файл.

Пакетный код работает только для Windows Vista и более поздних версий Windows из-за командыSetx по умолчанию недоступно в Windows XP или даже в предыдущих версиях Windows.

Для доступности командыSetx см. статью SS64 оSetX и MicrosoftSetX документация.

Дляreg.exe Различия выходных данных в Windows XP и более поздних версиях Windows см. в статье Роба ван дер ВудеЧтение реестра NT с помощью REG Query, Различный выходreg.exe учитывается код партии ниже.

Для объяснения, почему не использовать местныйPATH как в настоящее время определено на выполнение командного файла читать вопросы, ответы и комментарии

Как установить переменную среды PATH в командном файле только один раз в Windows?Почему другие пути к папкам также добавляются в системную переменную PATH с помощью SetX, а не только с указанным путем к папке?В чем причина работы nodemon в cmd, а не в командном файле?

Комментируемый пакетный код для удаления пути к папке от пользователя и системыДОРОЖКА:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "PathToRemove1=C:\Temp\Test"
set "PathToRemove2=C:\Temp"

rem Get directly from Windows registry the system PATH variable value.
for /F "skip=2 tokens=1,2*" %%N in ('%SystemRoot%\System32\reg.exe query "HKLM\System\CurrentControlSet\Control\Session Manager\Environment" /v "Path" 2^>nul') do (
    if /I "%%N" == "Path" (
        set "SystemPath=%%P"
        goto CheckSystemPath
    )
)
echo Error: System environment variable PATH not found in Windows registry.
echo/
goto UserPath

:CheckSystemPath
setlocal EnableDelayedExpansion
rem Does the system PATH not end with a semicolon, append one temporarily.
if not "!SystemPath:~-1!" == ";" set "SystemPath=!SystemPath!;"

rem Check case-insensitive for the folder paths to remove as defined at top
rem of this batch script and remove them if indeed found in system PATH.
set "PathModified=0"
for /F "tokens=1* delims==" %%I in ('set PathToRemove') do (
    if not "!SystemPath:%%J;=!" == "!SystemPath!" (
        set "SystemPath=!SystemPath:%%J;=!"
        set "PathModified=1"
    )
)

rem Replace all two or more ; in series by just one ; in system path.
:CleanSystem
if not "!SystemPath:;;=;!" == "!SystemPath!" set "SystemPath=!SystemPath:;;=;!" & goto CleanSystem

rem Remove the semicolon at end of system PATH if there is one.
if "!SystemPath:~-1!" == ";" set "SystemPath=!SystemPath:~0,-1!"

rem Update system PATH using command SETX which requires administrator
rem privileges if the system PATH needs to be modified at all.
if "%PathModified%" == "1" (
    %SystemRoot%\System32\setx.exe PATH "!SystemPath!" /M
)
endlocal

:UserPath
rem Get directly from Windows registry the user PATH variable value.
for /F "skip=2 tokens=1,2*" %%N in ('%SystemRoot%\System32\reg.exe query "HKCU\Environment" /v "Path" 2^>nul') do (
    if /I "%%N" == "Path" (
        set "UserPath=%%P"
        goto CheckUserPath
    )
)
rem This PATH variable does often not exist and therefore nothing to do here.
goto PathUpdateDone

:CheckUserPath
setlocal EnableDelayedExpansion
rem Does the user PATH not end with a semicolon, append one temporarily.
if not "!UserPath:~-1!" == ";" set "UserPath=!UserPath!;"

rem Check case-insensitive for the folder paths to remove as defined at top
rem of this batch script and remove them if indeed found in user PATH.
set "PathModified=0"
for /F "tokens=1* delims==" %%I in ('set PathToRemove') do (
    if not "!UserPath:%%J;=!" == "!UserPath!" (
        set "UserPath=!UserPath:%%J;=!"
        set "PathModified=1"
        if not defined UserPath goto DeleteUserPath
    )
)

rem Replace all two or more ; in series by just one ; in user path.
:CleanUser
if not "!UserPath:;;=;!" == "!UserPath!" set "UserPath=!UserPath:;;=;!" & goto CleanUser

rem Remove the semicolon at end of user PATH if there is one.
if "!UserPath:~-1!" == ";" set "UserPath=!UserPath:~0,-1!"
if not defined UserPath goto DeleteUserPath

rem Update user PATH using command SETX which does not require administrator
rem privileges if the user PATH needs to be modified at all.
if "%PathModified%" == "1" (
    %SystemRoot%\System32\setx.exe PATH "!UserPath!"
)
goto PathUpdateDone

:DeleteUserPath
rem Delete the user PATH as it contains only folder paths to remove.
%SystemRoot%\System32\reg.exe delete "HKCU\Environment" /v "Path" /f >nul

:PathUpdateDone
rem Other code could be inserted here.
endlocal
endlocal

Приведенный выше пакетный код использует простую подстановку строк без учета регистра и сравнение строк с учетом регистра, чтобы проверить, присутствует ли текущий путь для удаления в пользователе или системе.ДОРОЖКА, Это работает, только если хорошо известно, как пути к папкам были добавлены ранее, и пользователь не изменил их за это время. Для более безопасного метода проверки, еслиДОРОЖКА содержит путь к папке смотри ответ наКак проверить, существует ли каталог в% PATH%? написаноdbenham.

Внимание: Этот пакетный код не предназначен для обработки очень редких случаев использованиясистема или жепользователь PATH содержит путь к папке с одной или несколькими точками с запятой в строке пути, заключенной в двойные кавычки, чтобы получить; интерпретируется Windows внутри строки пути к двойным кавычкам как буквенный символ вместо разделителя между путями к папкам.

Чтобы понять используемые команды и то, как они работают, откройте окно командной строки, выполните там следующие команды и полностью прочитайте все страницы справки, отображаемые для каждой команды.

echo /?endlocal /?for /?goto /?if /?reg /?reg delete /?reg query /?rem /?set /?setlocal /?setx /?

Смотрите также статью Microsoft оИспользование операторов перенаправления команд для объяснения>nul а также2>nul с оператором перенаправления> быть сбежавшим с^ использовать перенаправление на выполнениеreg.exe вместо интерпретации2>nul неуместен для командыЗА что приведет к выходу пакетной обработки интерпретатором команд Windows из-за синтаксической ошибки.

 Jean-François Fabre29 июл. 2016 г., 22:57
+1! отличный ответ. Ну, я сделал то же самое в Python, потому что я не хотел идти по тому же пути, что и вы. Это отвечает на вопрос, но реальный вопрос: разумно ли пытаться сделать это в виде пакетного файла? (даже если это встроенные окна). Разве Microsoft не должна предоставлять безопасный способ делать такие вещи?
 Mofi30 июл. 2016 г., 18:02
я держуДОРОЖКА на моих компьютерах чисто. Существуют установщики приложений, которые добавляют пути к папкамДОРОЖКА хотя само по себе установленное приложение в этом не нуждается. Почему вообще был добавлен путь к папке? Если пользователь хочет использовать приложение из командной строки, он может это сделать. Другие приложения, которые действительно требуют добавления 1 или более папок вДОРОЖКА изменены мной. Я поместил их папки и переменные среды в пакетный файл и изменил ярлыки, используемые для запуска приложения, чтобы сначала запустить пакетный файл, настроить среду, а затем запустить приложение.
 Eilidh01 авг. 2016 г., 12:29
@Mofi FWIW причина, по которой несколько значений добавляются в PATH в процессе установки, потому что процесс установки добавляет в систему несколько зависимостей (например, Java). В моем личном случае это делается для удаления зависимостей.
 Mofi30 июл. 2016 г., 17:57
Ну, на мой взгляд, приложение, которое должно добавить 1 или несколько путей к папкамДОРОЖКА это просто чисто закодированное приложение. Разработчик приложения должен подумать о том, почему приложение (пакет) не работает без добавления одной или нескольких папок в систему или пользователя.ДОРОЖКА вместо того, чтобы думать, как обновитьДОРОЖКА переменная окружения. Только пользователь должен изменить пользователя или системуДОРОЖКА вообще, когда он / она хочет запускать приложения из командной строки, регулярно не находясь в стандартных путях Windows.
 Mofi30 июл. 2016 г., 18:11
@ Jean-FrançoisFabre Чтобы ответить на ваш вопрос: да, Microsoft должна предоставить безопасный способ.ДОРОЖКА Модификация любым приложением (установщик / деинсталлятор / реальное приложение) не должна быть возможна без уведомления пользователя и запроса подтверждения со стороны пользователя. Если это будет реализовано Microsoft, эти приложения манипулируютДОРОЖКА будет переписан скорее всего очень быстро, чтобы работать без модификацииДОРОЖКА, Приведенный выше командный файл используется мной для очистки системыДОРОЖКА после установки / обновления приложений всегда добавляйте их пути к папкамДОРОЖКА не разыскиваемый мной

Ваш ответ на вопрос