script reg modify comandos bat batch-file registry

batch file - modify - ¿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?



reg add bat (1)

Tengo un archivo por lotes al que llamo desde C ++ usando el system("name.bat") . En ese archivo por lotes estoy tratando de leer el valor de una clave de registro. Llamar al archivo por lotes desde C ++ hace que el set KEY_NAME=HKEY_LOCAL_MACHINE/stuff falle.

Sin embargo, cuando ejecuto directamente el archivo por lotes (haciendo doble clic en él), funciona bien. No estoy seguro de lo que estoy haciendo mal.

Archivo por lotes:

set KEY_NAME=HKEY_LOCAL_MACHINE/SOFTWARE/Ansoft/Designer/2014.0/Desktop set VALUE_NAME=InstallationDirectory REG QUERY %KEY_NAME% /v %VALUE_NAME%

Archivo C ++:

int main(void) { system("CALL C://HFSS//setup_vars.bat"); return 0; }

ACTUALIZACIÓN 1:

Descubrí que la clave está realmente en el registro de 64 bits, y estaba creando mi solución C ++ como una de 32 bits. Una vez que solucioné eso, encontré que la clave de registro estaba bien.

Ahora tengo un problema al agregar esa ruta a mi variable PATH . En lugar de crear una variable del sistema, está creando una variable de usuario PATH y agregándola allí.

Ejecutar desde la línea de comandos funciona.

Código:

set KEY_NAME=HKLM/SOFTWARE/Ansoft/Designer/2014.0/Desktop/ set VALUE_NAME=InstallationDirectory FOR /F "usebackq skip=1 tokens=1,2*" %%A IN (`REG QUERY %KEY_NAME% /v %VALUE_NAME%`) DO ( set ValueName=%%A set ValueType=%%B set ValueValue=%%C ) if defined ValueName ( @echo Value Value = %ValueValue% ) else ( @echo %KEY_NAME%/%VALUE_NAME% not found. ) :: Set PATH Variable set path_str=%PATH% set addPath=%ValueValue%; echo %addPath% echo %ValueValue% echo %PATH%| find /i "%addPath%">NUL if NOT ERRORLEVEL 1 ( SETX PATH "%PATH% ) else ( SETX PATH "%PATH%;%addPath%;" /M )

ACTUALIZACIÓN 2:

Moví la ubicación de la opción / M y ahora se agrega a la variable PATH derecha.

Sin embargo, cuando estoy haciendo esto, agrega la RUTA más de una vez (3 veces) y luego también agrega una ruta a la carpeta visual studio amd64.

Estoy seguro de por qué está sucediendo eso.


Windows crea una copia de la tabla de entorno completa del proceso que comienza un nuevo proceso para el nuevo proceso. Por lo tanto, al iniciar su aplicación C ++, su aplicación obtiene la tabla de entorno, incluida la RUTA del proceso principal, el Explorador de Windows o, en su caso, Visual Studio. Y esta RUTA se copia para cmd.exe al inicio del archivo por lotes.

Teniendo en cuenta todo el árbol de procesos desde el escritorio de Windows hasta el archivo por lotes, se han realizado muchas copias para PATH y algunos procesos quizás agregaron algo a su copia local de PATH como lo ha hecho Visual Studio, o incluso han eliminado rutas de PATH .

Lo que hace ahora con SETX PATH "%PATH% es agregar la copia local de PATH modificada por los procesos primarios en el árbol de procesos completamente a la RUTA del sistema sin verificar rutas duplicadas.

Mucho mejor sería tirar todo el código usando una copia local de PATH y, en su lugar, leer el valor de la RUTA del sistema, verificar si la ruta que desea agregar aún no está en la RUTA del sistema y, si este no es el caso, agregue la ruta que desea para agregar a la RUTA del sistema usando setx .

Y esto debe hacerse sin expandir las variables de entorno en la RUTA del sistema como %SystemRoot%/System32 a C:/Windows/System32 .

ACTUALIZAR

Aquí está el código de lote requerido para su tarea probada en Windows 7 x64 y Windows XP x86.

@echo off setlocal EnableExtensions DisableDelayedExpansion set "KeyName=HKLM/SOFTWARE/Ansoft/Designer/2014.0/Desktop" set "ValueName=InstallationDirectory" for /F "skip=2 tokens=1,2*" %%N in (''%SystemRoot%/System32/reg.exe query "%KeyName%" /v "%ValueName%" 2^>nul'') do ( if /I "%%N" == "%ValueName%" ( set "PathToAdd=%%P" if defined PathToAdd goto GetSystemPath ) ) echo Error: Could not find non-empty value "%ValueName%" under key echo %KeyName% echo/ endlocal pause goto :EOF :GetSystemPath 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 CheckPath ) ) echo Error: System environment variable PATH not found with a non-empty value. echo/ endlocal pause goto :EOF :CheckPath setlocal EnableDelayedExpansion rem The folder path to add must contain / (backslash) as directory rem separator and not / (slash) and should not end with a backslash. set "PathToAdd=%PathToAdd:/=/%" if "%PathToAdd:~-1%" == "/" set "PathToAdd=%PathToAdd:~0,-1%" set "Separator=" if not "!SystemPath:~-1!" == ";" set "Separator=;" set "PathCheck=!SystemPath!%Separator%" if "!PathCheck:%PathToAdd%;=!" == "!PathCheck!" ( set "PathToSet=!SystemPath!%Separator%!PathToAdd!" set "UseSetx=1" if not "!PathToSet:~1024,1!" == "" set "UseSetx=" if not exist %SystemRoot%/System32/setx.exe set "UseSetx=" if defined UseSetx ( %SystemRoot%/System32/setx.exe Path "!PathToSet!" /M >nul ) else ( set "ValueType=REG_EXPAND_SZ" if "!PathToSet:%%=!" == "!PathToSet!" set "ValueType=REG_SZ" %SystemRoot%/System32/reg.exe ADD "HKLM/System/CurrentControlSet/Control/Session Manager/Environment" /f /v Path /t !ValueType! /d "!PathToSet!" >nul ) ) endlocal endlocal

El código de lote anterior usa 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 de la carpeta a agregar ya está presente en la RUTA del sistema. Esto funciona solo si se sabe bien cómo se agregó la ruta de la carpeta antes y el usuario no ha modificado esta ruta de la carpeta en PATH 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 Dave Benham .

Nota 1: El comando setx no está disponible por defecto en Windows XP.

Nota 2: El comando setx trunca valores de más de 1024 caracteres a 1024 caracteres.

Por esa razón, el archivo por lotes utiliza el comando reg para reemplazar la RUTA del sistema en el registro de Windows si setx no está disponible o el nuevo valor de ruta es demasiado largo para setx . La desventaja de usar reg es que el mensaje WM_SETTINGCHANGE no se envía a todas las ventanas de nivel superior informando al Explorador de Windows que se ejecuta como escritorio de Windows y otras aplicaciones sobre este cambio de la variable de entorno del sistema. Por lo tanto, el usuario debe reiniciar Windows, lo que se hace mejor siempre al cambiar algo en las variables de entorno del sistema de Windows almacenadas persistentes.

El script por lotes se probó con PATH que contiene actualmente una ruta de carpeta con un signo de exclamación y una ruta de carpeta entre comillas dobles, que es necesaria solo si la ruta de carpeta contiene un punto y coma.

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 /?
  • pause /?
  • reg /? y reg add /? y reg query /?
  • set /?
  • setlocal /?
  • setx /?