如何使用 .bat 文件从 PATH 环境变量中删除特定标记? [英] How can I use a .bat file to remove specific tokens from the PATH environment variable?

查看:30
本文介绍了如何使用 .bat 文件从 PATH 环境变量中删除特定标记?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写卸载脚本,因此我想撤消"对系统进行的安装修改.为了实现这个目标,我想解析 PATH 变量,并删除安装添加到 PATH 的任何值.

I am writing an uninstallation script, so I would like to 'undo' modifications the installation made to the system. In achieving this goal, I would like to parse the PATH variable, and remove any values that the installation added to the PATH.

为此,我开发了以下伪代码 -

To do so, I developed the following pseudocode -

  • PATH的内容保存到一个临时变量
  • PATH分割成token,使用;字符作为分隔符,循环遍历每个token
  • (循环中)确定当前令牌是否是安装添加的令牌
  • (循环中)如果当前令牌不是由安装添加的,则将其保存以添加到更新的PATH(在临时变量中)
  • 保存更新后的PATH
  • Save the contents of PATH to a temporary variable
  • Split the PATH into tokens, using the ; character as a delimiter, and loop through each token
  • (In Loop) Identify if the current token is one added by the installation
  • (In Loop) If the current token was not added by the installation, save it to be added to the updated PATH (in a temporary variable)
  • Save the updated PATH

我希望这实现起来相对简单.

I expected this to be relatively straightforward to implement.

第一步,存储PATH很简单.

SET TEMP_PATH=%PATH% 

但是,当我尝试遍历每个令牌时,它不会按我预期的那样工作.

However, when I try to loop through each token, it will not work as I expected.

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

该命令只输出第一个token,不回显后续token.

This command only outputs the first token, and no subsequent tokens are echoed out.

所以,我有两个问题 -

So, I have two questions -

  • 如何遍历未知数量的令牌并处理每个令牌?
  • 是否有另一种可能更简单的方法来实现相同的目标?

谢谢.

推荐答案

下面的批处理代码删除了脚本顶部定义的 1 个或多个文件夹路径,PathToRemove1, PathToRemove2代码>, ...来自

The batch code below removes 1 or more folder paths as defined at top of the script with PathToRemove1, PathToRemove2, ... from

  • user PATH 存储在 Windows 注册表项下的当前用户帐户
    HKEY_CURRENT_USEREnvironment
  • system PATH 存储在 Windows 注册表项下
    HKEY_LOCAL_MACHINESystemCurrentControlSetControlSession ManagerEnvironment
  • user PATH of current user account stored in Windows registry under key
    HKEY_CURRENT_USEREnvironment
  • system PATH stored in Windows registry under key
    HKEY_LOCAL_MACHINESystemCurrentControlSetControlSession ManagerEnvironment

系统PATH的更新需要管理员权限,这意味着如果没有为执行批处理文件的用户帐户禁用用户帐户控制(UAC),则必须以管理员身份执行批处理文件.

The update of system PATH requires administrator privileges which means the batch file must be executed as administrator if user account control (UAC) is not disabled for the user account executing the batch file.

批处理代码仅适用于 Windows Vista 和更高版本的 Windows,因为命令 SETX 在默认情况下不适用于 Windows XP 甚至以前版本的 Windows.

The batch code works only for Windows Vista and later versions of Windows because of command SETX is by default not available on Windows XP or even former versions of Windows.

有关命令 SETX 的可用性,请参阅关于 SetX 的 SS64 文章和 Microsoft 的 SetX 文档.

For availability of command SETX see SS64 article about SetX and Microsoft's SetX documentation.

对于 reg.exe 在 Windows XP 与更高版本的 Windows 上的输出差异,请参阅 Rob van der Woude 的 使用 REG 查询读取 NT 的注册表.下面的批处理代码考虑了 reg.exe 的不同输出.

For the reg.exe output differences on Windows XP versus later Windows versions see Rob van der Woude's Reading NT's Registry with REG Query. The different output of reg.exe is taken into account by the batch code below.

有关为什么不使用当前在批处理文件执行时定义的本地 PATH 的解释,请阅读

For an explanation why not using local PATH as currently defined on execution of the batch file read the questions, answers and comments of

注释了从用户和系统中删除文件夹路径的批处理代码PATH:

Commented batch code for folder path removal from user and system PATH:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "PathToRemove1=C:TempTest"
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
eg.exe query "HKLMSystemCurrentControlSetControlSession ManagerEnvironment" /v "Path" 2^>nul') do (
    if /I "%%N" == "Path" (
        set "SystemPath=%%P"
        if defined SystemPath goto CheckSystemPath
    )
)
echo Error: System environment variable PATH not found with a value 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 System PATH should contain only backslashes and not slashes.
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 Remove a backslash 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. SETX is
rem by default not installed on Windows XP and truncates string values
rem longer than 1024 characters to 1024 characters. So use alternatively
rem command REG to add system PATH if command SETX cannot be used or is
rem not available at all.
if "%PathModified%" == "1" (
    set "UseSetx=1"
    if not "!SystemPath:~1024,1!" == "" set "UseSetx="
    if not exist %SystemRoot%System32setx.exe set "UseSetx="
    if defined UseSetx (
        %SystemRoot%System32setx.exe Path "!SystemPath!" /M >nul
    ) else (
        set "ValueType=REG_EXPAND_SZ"
        if "!SystemPath:%%=!" == "!SystemPath!" set "ValueType=REG_SZ"
        %SystemRoot%System32
eg.exe ADD "HKLMSystemCurrentControlSetControlSession ManagerEnvironment" /f /v Path /t !ValueType! /d "!SystemPath!" >nul
    )
)
endlocal

:UserPath
rem Get directly from Windows registry the user PATH variable value.
for /F "skip=2 tokens=1,2*" %%N in ('%SystemRoot%System32
eg.exe query "HKCUEnvironment" /v "Path" 2^>nul') do (
    if /I "%%N" == "Path" (
        set "UserPath=%%P"
        if defined UserPath goto CheckUserPath
        rem User PATH exists, but with no value, delete user PATH.
        goto DeleteUserPath
    )
)
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. SETX is
rem by default not installed on Windows XP and truncates string values
rem longer than 1024 characters to 1024 characters. So use alternatively
rem command REG to add user PATH if command SETX cannot be used or is
rem not available at all.
if "%PathModified%" == "1" (
    set "UseSetx=1"
    if not "!UserPath:~1024,1!" == "" set "UseSetx="
    if not exist %SystemRoot%System32setx.exe set "UseSetx="
    if defined UseSetx (
        %SystemRoot%System32setx.exe Path "!UserPath!" /M >nul
    ) else (
        set "ValueType=REG_EXPAND_SZ"
        if "!UserPath:%%=!" == "!UserPath!" set "ValueType=REG_SZ"
        %SystemRoot%System32
eg.exe ADD "HKCUEnvironment" /f /v Path /t !ValueType! /d "!UserPath!" >nul
    )
)
goto PathUpdateDone

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

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

上面的批处理代码使用简单的不区分大小写的字符串替换和区分大小写的字符串比较来检查要删除的当前路径是否存在于用户或系统PATH.仅当众所周知之前如何添加文件夹路径并且用户没有在此期间修改它们时,这才有效.有关检查 PATH 是否包含文件夹路径的更安全方法,请参阅 如何检查目录是否存在于%PATH%?dbenham 编写.

The batch code above uses a simple case-insensitive string substitution and a case-sensitive string comparison to check if the current path to remove is present in user or system PATH. This works only if it is well known how the folder paths were added before and the user has not modified them in the meantime. For a safer method of checking if PATH contains a folder path see the answer on How to check if directory exists in %PATH%? written by dbenham.

注意:此批处理代码并非旨在处理系统用户 PATH 包含一个文件夹路径,在双引号括起来的路径字符串中包含一个或多个分号,以获得 ; 在双引号文件夹路径字符串中被 Windows 解释为文字字符而不是文件夹路径之间的分隔符.

Attention: This batch code is not designed to handle the very rare use cases of system or user PATH contain a folder path with one or more semicolons in path string enclosed in double quotes to get the ; interpreted by Windows inside the double quoted folder path string as literal character instead of separator between the folder paths.

要了解使用的命令及其工作原理,请打开命令提示符窗口,在那里执行以下命令,并仔细阅读为每个命令显示的所有帮助页面.

For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.

  • echo/?
  • endlocal/?
  • for/?
  • 转到/?
  • if/?
  • reg/?
  • reg add/?
  • reg delete/?
  • reg 查询/?
  • rem/?
  • set/?
  • setlocal/?
  • setx/?

另见微软关于使用命令重定向操作符 解释>nul2>nul 使用重定向操作符>code> 使用 ^ 进行转义以在执行 reg.exe 时使用重定向,而不是解释 2>nul 为命令 FOR 错位 这将导致 Windows 命令解释器由于语法错误而退出批处理.

See also Microsoft's article about Using command redirection operators for an explanation of >nul and 2>nul with redirection operator > being escaped with ^ to use the redirection on execution of reg.exe instead of interpreting 2>nul misplaced for command FOR which would result in an exit of batch processing by Windows command interpreter because of a syntax error.

这篇关于如何使用 .bat 文件从 PATH 环境变量中删除特定标记?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆