Superando el límite de 1024 caracteres con setx

74

Estoy tratando de establecer variables de entorno utilizando el setxcomando, como el siguiente

setx PATH "f: \ herramientas comunes \ git \ bin; f: \ herramientas comunes \ python \ app; f: \ herramientas comunes \ python \ app \ scripts; f: \ herramientas comunes \ ruby ​​\ bin; f: \ masm32 \ bin; F: \ Borland \ BCC55 \ Bin;% PATH% "

Sin embargo, obtengo el siguiente error si el valor tiene más de 1024 caracteres de longitud:

ADVERTENCIA: Los datos que se guardan se truncan a 1024 caracteres.

ÉXITO: ​​se guardó el valor especificado.

Pero algunas de las rutas al final no se guardan en variable, supongo que debido al límite de caracteres como sugiere el error.

Madhur Ahuja
fuente
Hay una lista de formas alternativas para modificar el %PATH%al superuser.com/questions/297947
Ehtesh Choudhury
1
Busque en el Editor de entorno rápido que le permite editar todas las variables de entorno gráficamente (también puede guardar una copia de seguridad también).
ja72
3
¿Alguien más se molesta por este éxito de reclamo cuando claramente no hace lo que se le solicitó? ¿No es preocupante que esto no falle mientras deja el camino exactamente como era?
Chad Schouggins
¿Esto todavía se trunca en Windows 10?
cowlinator
1
Sí, lo hace en Windows 10
Ivan

Respuestas:

48

Su mejor opción es editar el registro directamente.

Navegue HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environmenty edite el Pathvalor (luego reinicie para activar el nuevo valor).

Sin embargo, tenga en cuenta que si bien puede ingresar una ruta muy larga (hasta la longitud variable máxima del entorno; 2,048 o 32,768 bytes dependiendo de la fuente), no todo el software podrá leerlo y manejarlo correctamente si es demasiado largo.

Synetech
fuente
1
¿Realmente se requiere reiniciar aquí? ¿Cómo lo hace setx? Setx no requiere reiniciar.
Madhur Ahuja
11
Sí, se requiere reiniciar. setxedita el registro como indiqué, luego emite un WM_SETTINGCHANGEmensaje. Esto le dice a todas las ventanas de nivel superior que la configuración del sistema ha cambiado (en este caso, una variable de entorno). Sin eso, Explorer y los programas que abriste con él no sabrán sobre el cambio. Usted podría transmitir el mensaje a sí mismo de forma manual (I escribió un programa para hacer precisamente eso, y un archivo por lotes para reemplazar SETXeso hace la edición del registro seguido de la emisión), pero al igual setxy de diálogo Propiedades del sistema varentorno, tiene efectos secundarios que las hacer reinicio preferible.
Synetech
2
Ah y editando un env.var. en realidad causa problemas si no reinicia porque cualquier variable de entorno que contenga otras variables dejará de expandirse. Por ejemplo, lo acabo de transmitir y ahora esta es mi ruta y recibo un error porque la ruta ahora está "rota" / vacía. Ninguno de los vars se expandirá correctamente nuevamente hasta que reinicie. Lamentablemente esto es "normal". :-|
Synetech
3
Encontré un pequeño script de PowerShell que transmitirá el mensaje WM_SETTINGCHANGE.
Justin Dearing
10
Puede usar el método de registro anterior a través del comando REG add y luego usar SETX para establecer alguna otra variable para sí mismo (es decir: SETX / M USERNAME% USERNAME%). Esto hará que se configure el mensaje WM_SETTINGCHANGE y le dará la posibilidad de establecer la ruta desde un archivo por lotes.
Arte el
30

Si está utilizando Windows Vista o superior, puede hacer un symbolic linka la carpeta. por ejemplo:

mklink /d C:\pf "C:\Program Files"
mklink /d C:\pf86 "C:\Program Files (x86)"

haría un enlace, así c:\pfsería su carpeta de archivos de programa. Eliminé 300 caracteres de mi camino usando este truco.

(Sé que no está relacionado con setx, pero es útil para las personas que buscan sobrecomprar en el límite de 1024 caracteres)

Reza
fuente
18

Puede usar un script de PowerShell similar al siguiente:

$newPath = 'f:\common tools\git\bin;f:\common tools\python\app;f:\common tools\python\app\scripts;f:\common tools\ruby\bin;f:\masm32\bin;F:\Borland\BCC55\Bin'
$oldPath = [Environment]::GetEnvironmentVariable('path', 'machine');
[Environment]::SetEnvironmentVariable('path2', "$($newPath);$($oldPath)",'Machine');

La llamada a la API Environment.SetEnvironmentVariable () se transmitirá, WM_SETTINGCHANGEpor lo que no es necesario reiniciar.

Justin Dearing
fuente
¿No necesita también la siguiente línea: [Entorno] :: SetEnvironmentVariable ('ruta', "$ newPath", 'Máquina');
Fedor Steeman
1
En la tercera línea, no estoy seguro de qué beneficio aportan los signos de dólar adicionales y los paréntesis. ¿No podrías simplemente decir [Environment]::SetEnvironmentVariable('path', "$newPath;$oldPath",'Machine')?
twasbrillig
1
@twasbrillig Solo tengo cuidado cuando incluyo una variable en una cadena. En este caso es innecesario.
Justin Dearing
3
Puede llamar a esto desde un símbolo del sistema de administrador:@"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" -NoProfile -ExecutionPolicy Bypass -Command "[Environment]::SetEnvironmentVariable('path',\"C:\Program Files (x86)\GNU\GnuPG;$([Environment]::GetEnvironmentVariable('path','Machine'))\",'Machine');"
Mark C
7

Esta herramienta de línea de comandos SetEnv de código abierto es buena para editar la RUTA y otras variables de entorno sin limitaciones. Utiliza un búfer dinámico para que no haya limitaciones estáticas como 1024.

http://www.codeproject.com/Articles/12153/SetEnv

Sin embargo, la elección de un% como prefijo para agregar a una variable podría haber sido mejor, ya que a veces dificulta la sintaxis si se usa con otras variables locales por lotes ...

Kharlos Dominguez
fuente
> La herramienta SetEnv es buena para editar la RUTA y otras variables de entorno sin limitaciones . De hecho, personalmente trabajé con Darka en esa página para ayudarme a mejorar SetEnv para que pueda soportar completamente la expansión / subvariables (la sección Expansión de variables dinámicas), lo que en realidad ayuda a reducir la longitud de la ruta sin procesar.
Synetech
4

Una herramienta muy superior a setx para la manipulación de rutas es pathed.exe . Desafortunadamente, se limita a editar la ruta.

Además de una experiencia de usuario superior a la de setx, no tiene un límite de 1024 caracteres. A diferencia de la manipulación directa del registro, esta aplicación utiliza la llamada API Environment.SetEnvironmentVariable () que emitirá WM_SETTINGCHANGE.

Justin Dearing
fuente
2
Hay una lista de otras herramientas (incluido pathed.exe) en
superuser.com/questions/297947/is-there-a-convenient-way-to-edit-path-in-windows-7
2

Mi forma favorita es cambiar los nombres de las carpetas en las variables PATH para usar los nombres 8.3. Esta respuesta de StackOverflow tiene un script impresionante (ejecutado desde un archivo .bat) que generará la versión "minificada" de toda la variable PATH, que luego puede pegar en el cuadro de diálogo Editar variable. La única advertencia es que necesitará dividir las partes SYSTEM y USER. A medida que la secuencia de comandos avanza y descubre la versión minimizada para cada carpeta, descarta y le alerta sobre cualquier ruta no válida / inexistente. Bonito bono de limpieza.

Andrew Steitz
fuente
Ten cuidado si lo has usado fsutil.exe behavior set disable8dot3 1.
Andrew Morton
@AndrewMorton buen punto, pero ¿no sería eso "manejado" por el hecho de que el script no "genera" el nombre 8.3, solo informa el nombre 8.3 que asignó el sistema de archivos? Entonces, si una carpeta no tenía un nombre 8.3, el script no propondría un sustituto. Sin embargo, usar fsutil 8dot3name stripDESPUÉS de usar el script definitivamente causaría problemas para las carpetas afectadas.
Andrew Steitz el
Desafortunadamente no tengo una unidad o sistema de repuesto para verificarlo. Sin embargo, después de haber usado algunos fsutil 8dot3name striphoy y considerando que (a) primero verifica el registro y (b) la ruta está almacenada en el registro, mi preocupación anterior puede no estar justificada, siempre y cuando el usuario no use la /fopción (forzar) .
Andrew Morton el
2

Puedes poner esta línea en tu BAT:

setx path "%%path%%;c:\drive\fr;c:\drive\installs\7z"

Ver el doble %%.

(Referencia: https://support.microsoft.com/en-us/kb/75634 )

Aminadav Glickshtein
fuente
Enlace ahora está roto
Ivan
1
¡ADVERTENCIA! Esto posiblemente romperá las cosas, escribirá %path%;c:\...[snip]...\7zen la pathvariable de usuario , dejando caer cualquier otra cosa que tenga allí.
Eugene Petrov
La variable de entorno PATH utilizada por los programas es una combinación de la máquina y las variables PATH locales. Además de destruir los datos actuales en la ruta local, no creo que esto haga nada. Tener %path%en la ruta local la variable de entorno no debería tener ningún efecto.
Annan
0

Si no es necesario mantener separadas la RUTA del sistema y la RUTA del usuario:

::setx /m truncate variable length to 1024 REG ADD 
REG ADD "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /v PATH /t REG_SZ /f /d "%PATH%"
::empty local path, use system wide only, else it will enlarge with every setx /m
setx PATH ""
::setx is dummy but propagate system wide variables with it
setx /m A A
fantastory
fuente
1
¿Puedes explicar un poco más sobre lo que estás sugiriendo aquí?
G-Man
Es solo un comando listo para usar para solucionar el límite de setx 1024 caracteres. El ejemplo se muestra directamente en la variable PATH. Aunque las respuestas anteriores son útiles, carecen de una solución final.
fantastory
0

Creo que la mejor manera es la siguiente (con PowerShell). De esta manera también evitarás el litmit de 1024 caracteres.

Puede ver el código en: https://gist.github.com/drazul/b92f780689bd89a0d2a7

#------------ Add path to system variable -------------------------------------

$path2add = ';C:\path;'
$systemPath = [Environment]::GetEnvironmentVariable('Path', 'machine');

If (!$systemPath.contains($path2add)) {
    $systemPath += $path2add
    $systemPath = $systemPath -join ';'
    [Environment]::SetEnvironmentVariable('Path', $systemPath, 'Machine');
    write-host "Added to path!"
    write-host $systemPath
}

#------------ Delete path from system variable --------------------------------

$path2delete = 'C:\path;'
$systemPath = [Environment]::GetEnvironmentVariable('Path', 'machine');

$systemPath = $systemPath.replace($path2delete, '')
$systemPath = $systemPath -join ';'

[Environment]::SetEnvironmentVariable('Path', $systemPath, 'Machine');

write-host "Deleted from path!"
write-host $systemPath

#------------ Clean system variable -------------------------------------------

$systemPath = [Environment]::GetEnvironmentVariable('Path', 'machine');

while ($systemPath.contains(';;')) {
    $systemPath = $systemPath.replace(';;', ';')
}

[Environment]::SetEnvironmentVariable('Path', $systemPath, 'Machine');

write-host "Cleaned path!"
write-host $systemPath
Drazul
fuente