batch-file command-line cmd

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

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ó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.