batch file - ¿Cómo puedo usar un archivo.bat para eliminar tokens específicos de la variable de entorno PATH?
batch-file command-line (2)
Este comando solo genera el primer token y no se repite ningún token posterior.
FOR /F "delims=;" %%A IN (%TEMP_PATH%) DO ECHO %%A
¿Cómo puedo recorrer un número desconocido de tokens y trabajar con cada uno?
Use el siguiente archivo por lotes.
SplitPath.cmd :
@echo off
setlocal
for %%a in ("%path:;=";"%") do (
echo %%~a
)
endlocal
Salida de ejemplo :
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
Notas:
-
Modifique el bucle
for
según corresponda para implementar el resto de su pseudocódigo.
Otras lecturas
- Un índice AZ de la línea de comando CMD de Windows : una excelente referencia para todo lo relacionado con la línea cmd de Windows.
- for - Condicionalmente ejecuta un comando varias veces.
- Editar / reemplazar variable : edite y reemplace los caracteres asignados a una variable de cadena.
Estoy escribiendo un script de desinstalación, por lo que me gustaría "deshacer" las modificaciones realizadas en la instalación del sistema.
Para lograr este objetivo, me gustaría analizar la variable
PATH
y eliminar cualquier valor que la instalación haya agregado a
PATH
.
Para hacerlo, desarrollé el siguiente pseudocódigo:
-
Guarde el contenido de
PATH
en una variable temporal -
Divide la
PATH
en tokens, usando el;
carácter como delimitador, y recorrer cada token - (En bucle) Identifique si el token actual es uno agregado por la instalación
-
(En bucle) Si la instalación no agregó el token actual, guárdelo para agregarlo a la
PATH
actualizada (en una variable temporal) -
Guarde la
PATH
actualizada
Esperaba que esto fuera relativamente sencillo de implementar.
El primer paso, almacenar la
PATH
es simple.
SET TEMP_PATH=%PATH%
Sin embargo, cuando intento recorrer cada token, no funcionará como esperaba.
FOR /F "delims=;" %%A IN (%TEMP_PATH%) DO ECHO %%A
Este comando solo genera el primer token y no se repiten los tokens posteriores.
Entonces, tengo dos preguntas:
- ¿Cómo puedo recorrer un número desconocido de tokens y trabajar con cada uno?
- ¿Hay otra forma de lograr el mismo objetivo que puede ser más simple?
Gracias.
El siguiente código de lote elimina 1 o más rutas de carpeta como se define en la parte superior de la secuencia de comandos con
PathToRemove1
,
PathToRemove2
, ... de
-
RUTA
de usuario de la cuenta de usuario actual almacenada en el registro de Windows bajo clave
HKEY_CURRENT_USER/Environment
-
RUTA del
sistema almacenada en el registro de Windows bajo clave
HKEY_LOCAL_MACHINE/System/CurrentControlSet/Control/Session Manager/Environment
La actualización de la RUTA del sistema requiere privilegios de administrador, lo que significa que el archivo por lotes debe ejecutarse como administrador si el control de cuenta de usuario (UAC) no está desactivado para la cuenta de usuario que ejecuta el archivo por lotes.
El código por lotes solo funciona para Windows Vista y versiones posteriores de Windows debido a que el comando SETX no está disponible de forma predeterminada en Windows XP o incluso en versiones anteriores de Windows.
Para conocer la disponibilidad del comando SETX, consulte el artículo SetX sobre SetX y la documentación de SetX de Microsoft.
Para
reg.exe
las diferencias de salida de
reg.exe
en Windows XP en comparación con versiones posteriores de Windows, consulte
el Registro de NT de
Rob van der Woude
con la consulta REG
.
El código de lote a continuación tiene en cuenta la salida diferente de
reg.exe
.
Para obtener una explicación de por qué no usar la
PATH
local como se define actualmente en la ejecución del archivo por lotes, lea las preguntas, respuestas y comentarios de
- ¿Cómo establecer la variable de entorno PATH en el archivo por lotes solo una vez en Windows?
- ¿Por qué también se agregan otras rutas de carpeta a la RUTA del sistema con SetX y no solo la ruta de carpeta especificada?
- ¿Cuál es la razón por la que nodemon funciona en cmd pero no en un archivo por lotes?
Código de lote comentado para la eliminación de la ruta de la carpeta de la RUTA del usuario y del sistema:
@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"
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%/System32/setx.exe set "UseSetx="
if defined UseSetx (
%SystemRoot%/System32/setx.exe Path "!SystemPath!" /M >nul
) else (
set "ValueType=REG_EXPAND_SZ"
if "!SystemPath:%%=!" == "!SystemPath!" set "ValueType=REG_SZ"
%SystemRoot%/System32/reg.exe ADD "HKLM/System/CurrentControlSet/Control/Session Manager/Environment" /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/reg.exe query "HKCU/Environment" /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%/System32/setx.exe set "UseSetx="
if defined UseSetx (
%SystemRoot%/System32/setx.exe Path "!UserPath!" /M >nul
) else (
set "ValueType=REG_EXPAND_SZ"
if "!UserPath:%%=!" == "!UserPath!" set "ValueType=REG_SZ"
%SystemRoot%/System32/reg.exe ADD "HKCU/Environment" /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/reg.exe delete "HKCU/Environment" /v "Path" /f >nul
:PathUpdateDone
rem Other code could be inserted here.
endlocal
endlocal
El código de lote anterior utiliza una simple sustitución de cadenas que no distingue entre mayúsculas y minúsculas y una comparación de cadenas que distingue entre mayúsculas y minúsculas para verificar si la ruta actual para eliminar está presente en la RUTA del usuario o del sistema. Esto funciona solo si se sabe bien cómo se agregaron las rutas de las carpetas antes y el usuario no las ha modificado mientras tanto. Para un método más seguro de verificar si PATH contiene una ruta de carpeta, vea la respuesta en ¿Cómo verificar si el directorio existe en% PATH%? escrito por dbenham .
Atención:
este código de lote no está diseñado para manejar los casos de uso muy raros del
sistema
o
la
PATH
usuario que
contiene una ruta de carpeta con uno o más puntos y comas en la cadena de ruta encerrada entre comillas dobles para obtener el
;
interpretado por Windows dentro de la cadena de la ruta de la carpeta entre comillas dobles como carácter literal en lugar de separador entre las rutas de la carpeta.
Para comprender los comandos utilizados y cómo funcionan, abra una ventana de símbolo del sistema, ejecute allí los siguientes comandos y lea con cuidado todas las páginas de ayuda que se muestran para cada comando.
-
echo /?
-
endlocal /?
-
for /?
-
goto /?
-
if /?
-
reg /?
-
reg add /?
-
reg delete /?
-
reg query /?
-
rem /?
-
set /?
-
setlocal /?
-
setx /?
Consulte también el artículo de Microsoft sobre el
uso de operadores de redirección de comandos
para obtener una explicación de
>nul
y
2>nul
con el operador de redirección
>
se escapa con
^
para usar la redirección en la ejecución de
reg.exe
lugar de interpretar
2>nul
fuera de lugar para el comando
FOR
que resultaría en una salida de procesamiento por lotes por el intérprete de comandos de Windows debido a un error de sintaxis.