Superare il limite di 1024 caratteri con setx


72

Sto cercando di impostare le variabili di ambiente usando il setxcomando, come segue

setx PATH "f: \ strumenti comuni \ git \ bin; f: \ strumenti comuni \ python \ app; f: \ strumenti comuni \ python \ app \ script; f: \ strumenti comuni \ ruby ​​\ bin; f: \ masm32 \ bin; F: \ Borland \ BCC55 \ bin;% PATH%"

Tuttavia, viene visualizzato il seguente errore se il valore è più lungo di 1024 caratteri:

ATTENZIONE: i dati salvati vengono troncati a 1024 caratteri.

SUCCESSO: il valore specificato è stato salvato.

Ma alcuni dei percorsi alla fine non vengono salvati in variabili, immagino a causa del limite di caratteri come suggerisce l'errore.


C'è un elenco di modi alternativi per modificare il file %PATH%all'indirizzo superuser.com/questions/297947
Ehtesh Choudhury,

1
Cerca in Rapid Environment Editor che ti consente di modificare graficamente tutte le variabili di ambiente (puoi anche salvare un backup).
Ja72,

3
Qualcun altro è infastidito da questo successo affermativo quando chiaramente non fa ciò che è stato richiesto? Non è preoccupante che questo non fallisca mentre lascia il percorso esattamente come è stato?
Chad Schouggins,

Questo si interrompe ancora su Windows 10?
cowlinator,

1
Sì, lo fa su Windows 10
Ivan

Risposte:


48

La soluzione migliore è modificare direttamente il registro.

Passare a HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environmente modificare il Pathvalore (quindi riavviare per attivare il nuovo valore).

Si noti tuttavia che mentre è possibile immettere un percorso molto lungo, (fino alla lunghezza massima della variabile di ambiente; 2.048 o 32.768 byte a seconda della fonte), non tutti i software saranno in grado di leggerlo e gestirlo correttamente se è troppo lungo.


1
Il riavvio è davvero richiesto qui? Come lo fa Setx? Setx non richiede il riavvio.
Madhur Ahuja,

11
Sì, è necessario un riavvio. setxmodifica il registro come indicato, quindi trasmette un WM_SETTINGCHANGEmessaggio. Questo dice a tutte le finestre di livello superiore che un'impostazione di sistema è cambiata (in questo caso una variabile d'ambiente). Senza questo, Explorer e i programmi che hai aperto con esso non sapranno del cambiamento. Si potrebbe trasmettere il messaggio da soli manualmente (ho scritto un programma per fare proprio questo, e un file batch per sostituire SETXquesto fa la modifica del registro seguita dalla trasmissione), ma proprio come setxe la finestra di dialogo Proprietà del sistema envvar, ha effetti collaterali che rendere preferibile il riavvio.
Synetech,

2
Oh e la modifica di un env.var. in realtà causa problemi se non si riavvia perché eventuali variabili di ambiente che contengono altre variabili smetteranno di essere espanse. Ad esempio, l'ho appena trasmesso e ora questo è il mio percorso e ricevo un errore perché il percorso è ora "rotto" / vuoto. Nessuno dei var si espanderà nuovamente correttamente fino al riavvio. Purtroppo questo è "normale". :-|
Synetech,

3
Ho trovato un piccolo script di PowerShell che trasmetterà il messaggio WM_SETTINGCHANGE.
Justin Dearing il

10
È possibile utilizzare il metodo di registro sopra riportato tramite il comando REG add e quindi utilizzare SETX per impostare un'altra variabile su se stesso (ovvero: SETX / M USERNAME% USERNAME%). Ciò causerà l'impostazione del messaggio WM_SETTINGCHANGE e ti darà la possibilità di impostare il percorso da un file batch.
Art

28

se si utilizza Windows Vista o versione successiva, è possibile accedere symbolic linkalla cartella. per esempio:

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

farebbe un collegamento così c:\pfsarebbe la cartella dei file del programma. Ho rasato 300 personaggi dal mio percorso usando questo trucco.

(So ​​che non è correlato a setx ma è utile per le persone che cercano un sovraccarico al limite di 1024 caratteri)


18

È possibile utilizzare uno script di PowerShell simile al seguente:

$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 chiamata API Environment.SetEnvironmentVariable () verrà trasmessa, WM_SETTINGCHANGEquindi non è necessario riavviare.


Non hai bisogno anche della seguente riga: [Environment] :: SetEnvironmentVariable ('path', "$ newPath", 'Machine');
Fedor Steeman,

1
Nella terza riga, non sono sicuro di quale beneficio appaiano i segni del dollaro in più e le parentesi. Non potresti semplicemente dirlo [Environment]::SetEnvironmentVariable('path', "$newPath;$oldPath",'Machine')?
twasbrillig,

1
@twasbrillig Sto solo attento quando includo una variabile in una stringa. in questo caso non è necessario.
Justin Dearing il

3
Puoi chiamarlo da un prompt dei comandi dell'amministratore:@"%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');"
Segna C

7

Questo strumento da riga di comando SetEnv open source è utile per modificare il PERCORSO e altre variabili di ambiente senza limitazioni. Utilizza un buffer dinamico, quindi nessuna limitazione statica come 1024.

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

La scelta di un% come prefisso da aggiungere a una variabile avrebbe potuto essere migliore, dato che a volte rende difficile la sintassi se utilizzata con altre variabili locali batch ...


> Lo strumento SetEnv è utile per modificare il PERCORSO e le altre variabili d'ambiente senza limitazioni . In effetti, avevo lavorato personalmente con Darka su quella pagina per aiutare a migliorare ulteriormente SetEnv in modo che potesse supportare completamente l'espansione / sotto-variabili (la sezione Espansione variabile dinamica), che in realtà aiuta a ridurre la lunghezza del percorso non elaborato.
Synetech,

4

Uno strumento di gran lunga superiore a setx per la manipolazione del percorso è pathed.exe . Sfortunatamente, è limitato alla modifica del percorso.

Oltre a un'esperienza utente superiore a setx, non hai un limite di 1024 caratteri. A differenza della manipolazione diretta del registro, questa applicazione utilizza la chiamata API Environment.SetEnvironmentVariable () che trasmetterà WM_SETTINGCHANGE.


2
C'è un elenco di altri strumenti (incluso pathed.exe) su superuser.com/questions/297947/is-there-a-convenient-way-to-edit-path-in-windows-7
Ehtesh Choudhury


2

Il mio modo preferito è cambiare i nomi delle cartelle nelle variabili PATH per usare i nomi 8.3. Questa risposta StackOverflow ha un fantastico script (eseguito da un file .bat) che genererà la versione "minimizzata" dell'intera variabile PATH, che puoi quindi incollare nelle finestre di dialogo Modifica variabile. L'unica avvertenza è che dovrai dividere le parti SYSTEM e USER. Man mano che lo script esamina e individua la versione minimizzata per ogni cartella, scarta e avvisa l'utente di eventuali percorsi non validi / inesistenti. Bel bonus di pulizia.


Fai attenzione se hai usato fsutil.exe behavior set disable8dot3 1.
Andrew Morton,

@AndrewMorton è un buon punto, ma non sarebbe "gestito" dal fatto che lo script non "genera" il nome 8.3, ma riporta semplicemente il nome 8.3 assegnato dal file system? Quindi se una cartella non avesse un nome 8.3, lo script non proporrebbe un sostituto. Tuttavia, l'utilizzo di fsutil 8dot3name stripAFTER utilizzando lo script provocherebbe sicuramente problemi per le cartelle interessate.
Andrew Steitz,

Sfortunatamente non ho un'unità o un sistema di riserva per controllarlo. Tuttavia, dopo averne usato alcuni fsutil 8dot3name stripoggi e considerando che (a) controlla prima il registro e (b) il percorso è archiviato nel registro, la mia preoccupazione precedente potrebbe essere ingiustificata, a condizione che l'utente non utilizzi l' /fopzione (force) .
Andrew Morton,

2

Puoi inserire questa riga nella tua BAT:

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

Vedi il doppio %%.

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


Il link ora è rotto
Ivan

1
AVVERTIMENTO! Questo probabilmente romperà le cose, scriverà %path%;c:\...[snip]...\7zsulla pathvariabile utente , lasciando cadere qualsiasi altra cosa tu abbia avuto lì.
Eugene Petrov,

La variabile d'ambiente PATH utilizzata dai programmi è una combinazione della macchina e delle variabili PATH locali. Oltre a distruggere i dati attuali nel percorso locale, non penso che questo faccia qualcosa. Avere %path%nel percorso locale la variabile d'ambiente non dovrebbe avere alcun effetto.
Annan

0

se non è necessario mantenere separati PATH di sistema e PATH dell'utente:

::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

1
Puoi spiegare qualcosa in più su ciò che stai suggerendo qui?
G-Man,

È solo un comando pronto all'uso per risolvere il limite di setx 1024 caratteri. L'esempio è mostrato direttamente sulla variabile PATH. Sebbene le risposte precedenti siano utili, mancano di una soluzione finale.
fantastico

0

Penso che il modo migliore sia il prossimo (con PowerShell). In questo modo eviti anche la lite di 1024 caratteri.

Puoi vedere il codice su: 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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.