Überwindung der Zeichenbegrenzung von 1024 mit setx

73

Ich versuche, Umgebungsvariablen mit dem setxBefehl wie folgt festzulegen

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

Ich erhalte jedoch die folgende Fehlermeldung, wenn der Wert länger als 1024 Zeichen ist:

WARNUNG: Die gespeicherten Daten werden auf 1024 Zeichen gekürzt.

ERFOLG: Angegebener Wert wurde gespeichert.

Aber einige der Pfade am Ende werden nicht in Variablen gespeichert, da die Anzahl der Zeichen begrenzt ist, wie der Fehler vermuten lässt.

Madhur Ahuja
quelle
Es gibt eine Liste von alternativen Möglichkeiten , die bearbeiten %PATH%bei superuser.com/questions/297947
Ehtesh Choudhury
1
Schauen Sie in den Rapid Environment Editor, in dem Sie alle Umgebungsvariablen grafisch bearbeiten können (Sie können auch ein Backup speichern).
ja72
3
Ist jemand anderes von diesem behaupteten Erfolg betroffen, wenn er eindeutig nicht das tut, was gefordert wurde? Ist es nicht beunruhigend, dass dies nicht scheitert, wenn man den Pfad so verlässt, wie er war?
Chad Schouggins
Wird dies unter Windows 10 immer noch abgeschnitten?
Cowlinator
1
Ja, es funktioniert unter Windows 10
Ivan

Antworten:

48

Am besten bearbeiten Sie die Registrierung direkt.

Navigieren Sie zu HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environmentdem PathWert und bearbeiten Sie ihn (und starten Sie ihn neu, um den neuen Wert zu aktivieren).

Beachten Sie jedoch, dass Sie zwar einen sehr langen Pfad eingeben können (bis zur maximalen Länge der Umgebungsvariablen; 2.048 oder 32.768 Byte, abhängig von der Quelle), jedoch nicht alle Softwareprogramme in der Lage sind, ihn zu lesen und korrekt zu verarbeiten, wenn er zu lang ist.

Synetech
quelle
1
Ist hier wirklich ein Neustart erforderlich? Wie macht setx das? Setx erfordert keinen Neustart.
Madhur Ahuja
11
Ja, ein Neustart ist erforderlich. setxbearbeitet die Registrierung wie angegeben und sendet dann eine WM_SETTINGCHANGENachricht. Dies teilt allen Fenstern der obersten Ebene mit, dass sich eine Systemeinstellung geändert hat (in diesem Fall eine Umgebungsvariable). Ohne das wissen der Explorer und die damit geöffneten Programme nichts über die Änderung. Sie können die Nachricht auch manuell senden (ich habe ein Programm dafür geschrieben und eine Batch-Datei, die ersetzt werden muss SETX, damit die Registrierung bearbeitet wird, gefolgt von der Übertragung), aber genau wie setxder Envvar-Dialog mit den Systemeigenschaften hat dies auch Nebenwirkungen einen Neustart vorziehen.
Synetech,
2
Ach ja und eine env.var bearbeiten. verursacht tatsächlich Probleme, wenn Sie nicht neu starten, da Umgebungsvariablen, die andere Variablen enthalten, nicht mehr erweitert werden. Zum Beispiel, ich habe es gerade gesendet und jetzt ist dies mein Pfad und ich erhalte eine Fehlermeldung, weil der Pfad jetzt "kaputt" / leer ist. Keiner der Vars wird wieder ordnungsgemäß erweitert, bis ich einen Neustart durchführe. Das ist leider "normal". :-|
Synetech
3
Ich habe ein kleines PowerShell-Skript gefunden , das die Nachricht WM_SETTINGCHANGE sendet.
Justin Dearing
10
Sie können die obige Registrierungsmethode über den Befehl REG add verwenden und dann mit SETX eine andere Variable auf sich selbst setzen (z. B .: SETX / M USERNAME% USERNAME%). Dadurch wird die Meldung WM_SETTINGCHANGE festgelegt, und Sie können den Pfad aus einer Stapeldatei festlegen.
Kunst
29

Wenn Sie Windows Vista oder höher verwenden, können Sie ein symbolic linkin den Ordner machen. zum Beispiel:

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

würde einen Link machen, so c:\pfwäre Ihr Programmordner. Mit diesem Trick habe ich 300 Zeichen von meinem Weg gestrichen.

(Ich weiß, es hat nichts mit setx zu tun, aber es ist nützlich für Leute, die über 1024 Zeichen hinweg suchen.)

Reza
quelle
18

Sie können ein PowerShell-Skript verwenden, das dem folgenden ähnelt:

$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');

Der API-Aufruf Environment.SetEnvironmentVariable () wird rundgesendet, WM_SETTINGCHANGEsodass Sie nicht neu starten müssen.

Justin Dearing
quelle
Benötigen Sie nicht auch die folgende Zeile: [Environment] :: SetEnvironmentVariable ('path', "$ newPath", 'Machine');
Fedor Steeman
1
In der dritten Zeile bin ich mir nicht sicher, welchen Nutzen die zusätzlichen Dollarzeichen und Klammern bringen. Könntest du nicht einfach sagen [Environment]::SetEnvironmentVariable('path', "$newPath;$oldPath",'Machine')?
Twasbrillig
1
@twasbrillig Ich bin nur vorsichtig, wenn ich eine Variable in einen String einbinde. in diesem Fall ist es nicht notwendig.
Justin Dearing
3
Sie können dies von einer Administrator-Eingabeaufforderung aus aufrufen:@"%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');"
Markieren Sie C
7

Mit diesem Open-Source-Befehlszeilentool SetEnv können Sie PATH und andere Umgebungsvariablen ohne Einschränkungen bearbeiten. Es wird ein dynamischer Puffer verwendet, daher gibt es keine statischen Einschränkungen wie bei 1024.

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

Die Wahl eines% als Präfix zum Anhängen an eine Variable hätte jedoch besser sein können, da die Syntax manchmal schwierig ist, wenn sie mit anderen lokalen Stapelvariablen verwendet wird ...

Kharlos Dominguez
quelle
> Mit dem SetEnv-Tool können Sie PATH und andere Umgebungsvariablen ohne Einschränkungen bearbeiten . Tatsächlich habe ich auf dieser Seite persönlich mit Darka zusammengearbeitet, um SetEnv noch besser zu machen, sodass es die Erweiterung / Untervariablen (Abschnitt "Dynamische Variablenerweiterung") vollständig unterstützen kann, was tatsächlich dazu beiträgt, die Länge des Rohpfads zu verringern .
Synetech
4

Ein weitaus besseres Tool als setx zur Manipulation von Pfaden ist pathed.exe . Leider ist es auf die Bearbeitung des Pfades beschränkt.

Zusätzlich zu einer besseren Benutzererfahrung als bei setx gibt es keine Beschränkung auf 1024 Zeichen. Im Gegensatz zur direkten Manipulation der Registrierung verwendet diese Anwendung den API-Aufruf Environment.SetEnvironmentVariable (), der rundgesendet wird WM_SETTINGCHANGE.

Justin Dearing
quelle
2
Eine Liste weiterer Tools (einschließlich pathed.exe) finden Sie unter superuser.com/questions/297947/is-there-a-convenient-way-to-edit-path-in-windows-7
Ehtesh Choudhury
2

Am liebsten ändere ich die Ordnernamen in den PATH-Variablen, um die 8.3-Namen zu verwenden. Diese StackOverflow-Antwort enthält ein hervorragendes Skript (das von einer .bat-Datei ausgeführt wird), das die "verkleinerte" Version der gesamten PATH-Variablen generiert, die Sie dann in die Dialogfelder "Variable bearbeiten" einfügen können. Die einzige Einschränkung ist, dass Sie die Teile SYSTEM und USER aufteilen müssen. Während das Skript die minimierte Version für jeden Ordner durchläuft und herausfindet, werden ungültige / nicht vorhandene Pfade verworfen und gemeldet. Netter kleiner Aufräumbonus.

Andrew Steitz
quelle
Seien Sie vorsichtig, wenn Sie verwendet haben fsutil.exe behavior set disable8dot3 1.
Andrew Morton
@ AndrewMorton guter Punkt, aber würde das nicht durch die Tatsache "gehandhabt" werden, dass das Skript den 8.3-Namen nicht "generiert", sondern nur den 8.3-Namen meldet, den das Dateisystem zugewiesen hat? Wenn also ein Ordner keinen 8.3-Namen hätte, würde das Skript keinen Ersatz vorschlagen. Die Verwendung von fsutil 8dot3name stripAFTER mit dem Skript würde jedoch definitiv Probleme für die betroffenen Ordner verursachen.
Andrew Steitz
Leider habe ich kein Ersatzlaufwerk oder -system, um es zu überprüfen. Nachdem ich fsutil 8dot3name stripheute einige früher verwendet habe und bedenke, dass (a) zuerst die Registrierung überprüft wird und (b) der Pfad in der Registrierung gespeichert wird, kann mein früheres Anliegen unbegründet sein, solange der Benutzer nicht die /fOption (force) verwendet .
Andrew Morton
2

Sie können diese Zeile in Ihr BAT einfügen:

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

Siehe das Doppelte %%.

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

Aminadav Glickshtein
quelle
Link ist jetzt kaputt
Ivan
1
WARNUNG! Dies kann zu Fehlern führen, es wird %path%;c:\...[snip]...\7zin die Benutzervariable geschrieben pathund alles andere, was Sie dort hatten, verworfen.
Eugene Petrov
Die PATH-Umgebungsvariable, die von Programmen verwendet wird, ist eine Kombination aus der Maschine und lokalen PATH-Variablen. Ich glaube nicht, dass dies etwas bewirkt, außer dass die aktuellen Daten im lokalen Pfad zerstört werden. Das Vorhandensein einer %path%Umgebungsvariablen im lokalen Pfad sollte keine Auswirkungen haben.
Annan
0

Wenn es nicht erforderlich ist, Systempfad und Benutzerpfad getrennt zu halten, gehen Sie wie folgt vor:

::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
fantastisch
quelle
1
Können Sie uns etwas näher erläutern, was Sie hier vorschlagen?
G-Man
Es ist nur ein gebrauchsfertiger Befehl, um das Zeichenlimit von setx 1024 zu umgehen. Das Beispiel wird direkt auf der PATH-Variablen angezeigt. Obwohl die vorherigen Antworten hilfreich sind, fehlt ihnen eine endgültige Lösung.
fantastische
0

Ich denke, der beste Weg ist der nächste (mit Powershell). Auf diese Weise vermeiden Sie auch das Litmit von 1024 Zeichen.

Sie finden den Code unter: 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
quelle