Wie vermeiden Sie, dass die PATH-Umgebungsvariable in Windows überfüllt wird?


115

Ich würde gerne wissen, mit welchen Ansätzen Sie die ausführbaren Dateien in Ihrem System verwalten. Zum Beispiel habe ich fast alles über die Befehlszeile zugänglich, aber jetzt komme ich an die Grenze der Pfadzeichenfolge, sodass ich kein Verzeichnis mehr hinzufügen kann.

Was empfehlen Sie? Vor langer Zeit habe ich versucht, softLinks der ausführbaren Dateien in einem Verzeichnis zu verwenden, das zum Pfad gehört, aber dieser Ansatz hat nicht funktioniert. Werfen Sie die "nur ausführbare Datei" auf eine bekannte Dir, hat die Probleme, dass fast jede Anwendung eine Reihe von Dateien benötigt, so dass dies auch schlecht ist. Werfen Sie die ausführbare Datei und alle seine Dateien in ein bekanntes Verzeichnis, mmm das wird funktionieren, aber die Möglichkeit, einen Konflikt im Namen der Dateien zu bekommen, ist sehr, sehr hoch. Einen HardLink erstellen? ich weiß es nicht. Was denken Sie?


Warum benutzt du so viele Pfade? Der Pfad wird normalerweise für ein allgemeines Verzeichnis verwendet, wenn Ihre App das erweiterte Objekt / app / lib für andere freigeben muss. Verwenden Sie so viel, dass die App langsamer startet. Können Sie detaillierter angeben, wie Sie die Pfadumgebung var verwenden?
Pinichi

1
Hallo Pinichi, viele Anwendungen verwenden den Standard "C: \ Program File \ AppNAme \ ...". In meinem Fall können viele dieser Anwendungen über eine Befehlszeile ausgeführt werden oder müssen für andere Apps zugänglich sein ( Zum Beispiel die ausführbaren Dateien von Miktex, von denen jeder Tex-Editor erwartet, dass sie existieren. Sie müssen sich also im PATH befinden. Ich möchte keinen besseren Ansatz kennen, weil meiner nicht nachhaltig ist
mjsr

1
Dieses Tool komprimiert die Pfade. Das Ergebnis ist beeindruckend: uweraabe.de/Blog/2014/09/09/the-garbled-path-variable/#more-337
InTheNameOfScience

Antworten:


84

Eine Möglichkeit, die ich mir vorstellen kann, besteht darin, andere Umgebungsvariablen zum Speichern von Teilpfaden zu verwenden. Zum Beispiel, wenn Sie haben

C:\this_is_a\long_path\that_appears\in_multiple_places\subdir1;
C:\this_is_a\long_path\that_appears\in_multiple_places\subdir2;

Dann können Sie eine neue Umgebungsvariable erstellen, z

SET P1=C:\this_is_a\long_path\that_appears\in_multiple_places

Danach werden Ihre ursprünglichen Wege

%P1%\subdir1;
%P1%\subdir2;

BEARBEITEN: Eine weitere Option besteht darin, ein binVerzeichnis zu erstellen , das .batDateien enthält, die auf die entsprechenden .exeDateien verweisen .

BEARBEITEN 2: In dem Kommentar von Ben Voigt zu einer anderen Antwort wird erwähnt, dass die Verwendung anderer Umgebungsvariablen, wie vorgeschlagen, die Länge möglicherweise nicht verkürzt, %PATH%da sie vor dem Speichern erweitert werden. Dies mag wahr sein und ich habe es nicht getestet. Eine andere Option ist jedoch die Verwendung von 8dot3-Formularen für längere Verzeichnisnamen. Dies C:\Program Filesentspricht beispielsweise normalerweise C:\PROGRA~1. Sie können verwenden dir /x, um die kürzeren Namen zu sehen.

EDIT 3: Dieser einfache Test lässt mich glauben, dass Ben Voigt Recht hat.

set test1=hello
set test2=%test1%hello
set test1=bye
echo %test2%

Am Ende sehen Sie hellohelloeher die Ausgabe als byehello.

BEARBEITEN 4: Wenn Sie sich entscheiden, Batchdateien zu verwenden, um bestimmte Pfade zu entfernen %PATH%, sind Sie möglicherweise besorgt darüber, wie Sie Argumente aus Ihrer Batchdatei an Ihre ausführbare Datei weitergeben können, sodass der Prozess transparent ist (dh Sie werden keinen Unterschied bemerken zwischen dem Aufrufen der Batch-Datei und dem Aufrufen der ausführbaren Datei). Ich habe nicht viel Erfahrung mit dem Schreiben von Batch-Dateien, aber das scheint gut zu funktionieren.

@echo off

rem This batch file points to an executable of the same name
rem that is located in another directory. Specify the directory
rem here:

set actualdir=c:\this_is\an_example_path

rem You do not need to change anything that follows.

set actualfile=%0
set args=%1
:beginloop
if "%1" == "" goto endloop
shift
set args=%args% %1
goto beginloop
:endloop
%actualdir%\%actualfile% %args%

In der Regel sollten Sie beim Ausführen von Batchdateien aus dem Internet vorsichtig sein, da Sie mit Batchdateien alles Mögliche tun können, z. B. das Formatieren Ihrer Festplatte. Wenn Sie dem obigen Code (den ich geschrieben habe) nicht vertrauen, können Sie ihn testen, indem Sie die Zeile ersetzen

%actualdir%\%actualfile% %args%

mit

echo %actualdir%\%actualfile% %args%

Idealerweise sollten Sie genau wissen, was jede Zeile tut, bevor Sie sie ausführen.


1
Das 8dot3-Formular funktioniert gut, aber für wirklich große Verzeichnisse ist es nicht allzu groß, z. B. "C: \ Programme (x86) \ Microsoft Visual Studio 2008 SDK \ VisualStudioIntegration \ Tools \ Sandcastle \ ProductionTools \". Eine andere Sache, die ein wenig spart, war, dass ich als Benutzer eine PATH-Variable basierend auf dem Systempfad erstellen und jede andere Dir hinzufügen konnte. Alle diese Ansätze sind vom Typ "compact that string", aber können wir wie Unix ein zentrales Verzeichnis von Binärdateien haben?
mjsr

1
Hmm, in Bezug auf sehr lange Verzeichnisse würde ich das Gegenteil für richtig halten: Je länger das Verzeichnis, desto mehr Zeichen speichern Sie im 8dot3-Format. Wenn die Navigation schwierig ist cmd, beachten Sie, dass Sie die *Eingabe speichern können. Geben Sie beispielsweise von root aus ein dir /x pro*. Dort sehen Sie Ihr gewünschtes Verzeichnis zusammen mit seinem 8dot3-Namen. Verwenden Sie dann, cdum dorthin zu navigieren und den Vorgang zu wiederholen.
Mitch Schwartz

1
In Bezug auf UNIX gibt es eine, $PATHdie sehr ähnlich wie %PATH%in Windows funktioniert , daher bin ich mir nicht sicher, worum es Ihnen genau geht. Konventionell sind UNIX-Verzeichnisnamen in der Regel kürzer als in Windows und daher $PATHauch kürzer.
Mitch Schwartz

2
Vielen Dank, Mitch, das von Ihnen bereitgestellte Edit 4 ist genau das, was ich wollte! Jetzt kann ich einen zentralen Ordner mit allen benötigten Binärdateien haben. Ich werde mehr in der Tiefe testen, um zu sehen, ob es ein Problem mit einer App gibt
mjsr

2
Ihr Abschnitt 'Bearbeiten 4' ist zu kompliziert, um Argumente an die ausführbare Datei zu übergeben. Siehe Michael Burrs Antwort.
Dave Andersen

83

Dadurch wird Ihre Umgebungsvariable% PATH% analysiert und jedes Verzeichnis in sein Kurznamenäquivalent konvertiert. Anschließend wird alles wieder zusammengesetzt:

@echo off

SET MyPath=%PATH%
echo %MyPath%
echo --

setlocal EnableDelayedExpansion

SET TempPath="%MyPath:;=";"%"
SET var=
FOR %%a IN (%TempPath%) DO (
    IF exist %%~sa (
        SET "var=!var!;%%~sa"
    ) ELSE (
        echo %%a does not exist
    )
)

echo --
echo !var:~1!

Nehmen Sie die Ausgabe und aktualisieren Sie die PATH-Variable in Umgebungsvariablen.


Danke das war sehr nützlich !! Es hat meinen Weg von 1990 bis 1338 verkürzt und alles funktioniert immer noch wie ein Zauber! Ich habe mich für Ihren Ansatz entschieden, weil ich alles auf meinem Weg behalten wollte und das Verknüpfen über Batch-Dateien zu zeitaufwändig gewesen wäre. VIELEN DANK!
Ndrizza

2
Dies war auch nützlich, weil es mir über alle nicht existierenden Verzeichnisse in meinem Pfad erzählte, die sich im Laufe der Zeit angesammelt hatten.
Nate Glenn

27
Der Rapid Environment Editor ist eine weitere Möglichkeit, dies zu tun. Es hebt nicht vorhandene Verzeichnisse hervor und verfügt über die Option "langen Pfad in kurzen konvertieren".
Russell Gallop

3
@ RussellGallop: Das ist ein großartiges Werkzeug, Sir.
elo80ka

1
Beachten Sie das fehlende Schlusszitat danach %%~sa. Ich habe versucht, die Antwort zu aktualisieren, aber es lässt mich nicht, wenn ich nicht 6 Zeichen
ändere

28

Wenn Sie Windows Vista oder höher verwenden, können Sie einen symbolischen Link zum Ordner erstellen. beispielsweise:

mklink /d C:\pf "C:\Program Files"

würde einen Link machen, c:\pfwäre also dein program filesOrdner. Mit diesem Trick habe ich 300 Zeichen von meinem Weg entfernt.


Dies ist eine gute Alternative zur Verwendung einer Umgebungsvariablen zur Darstellung eines Teilpfads.
Porcus

1
Dies würde definitiv mehr helfen, aber wenn Sie eine "korrektere" (unterstützte?) Lösung wünschen , können Sie Instanzen von c:\Program Filesund c:\Program Files (x86)durch die vordefinierten Variablen %ProgramFiles%und %ProgramFiles(x86)% tenforums.com/tutorials/… ersetzen. Diese speichern jeweils nur wenige Zeichen , aber wenn Sie WIRKLICH kurz davor stehen, PATH zu maximieren, könnte dies der Unterschied sein. In diesem Fall werde ich% pf% und% pfx% erstellen, die in die richtigen Pfade aufgelöst werden. Danke für die Idee! :)
rainabba

Das Problem bei der Verwendung von Variablen wie% pf% und% pfx% besteht darin, dass Sie dieselben Probleme wie beim Erstellen symbolischer Links haben. Durch Software-Updates werden der Pfadvariablen möglicherweise wieder Dinge hinzugefügt. Das andere Problem bei der Verwendung solcher Variablen ist, dass es nicht schnell und einfach ist, Dinge um sie herum zu skripten oder vom Explorer aus zu ihnen zu navigieren. Mit der von mir beschriebenen Methode können Sie c: \ PF buchstäblich öffnen. Windows sieht es wie einen Ordner, sodass Sie auch ganz einfach Fledermaus oder Powershell dagegen schreiben können.
bmg002

10

Falls jemand interessiert ist ...

Ich finde, ich brauche nie wirklich alle diese Pfade auf einmal, also erstelle ich eine Reihe von "Initialisierungs" -Batchdateien, die den Pfad entsprechend ändern.

Wenn ich beispielsweise eine C ++ - Entwicklung in Eclipse durchführen möchte, würde ich Folgendes tun:

> initmingw
> initeclipse
> eclipse

Dies ist auch praktisch, um Konflikte zwischen gleichnamigen ausführbaren Dateien (z. B. den C ++ - und D-Compilern, die beide eine make.exe haben) zu vermeiden.

Meine Batch-Dateien sehen normalerweise so aus:

@echo off
set PATH=C:\Path\To\My\Stuff1;%PATH%
set PATH=C:\Path\To\My\Stuff2;%PATH%

Ich finde diesen Ansatz relativ sauber und habe noch keine Probleme damit.


7

Ich muss mich im Allgemeinen nicht darum kümmern (ich bin nicht auf eine Pfadgrößenbeschränkung gestoßen - ich weiß nicht einmal, was das auf modernen Windows-Systemen ist), aber hier ist, was ich tun könnte, um zu vermeiden, dass das Verzeichnis eines Programms abgelegt wird der Weg:

  • Die meisten Befehlszeilenprogramme werden in ein c:\utilVerzeichnis geworfen , das sich auf dem Pfad befindet
  • Andernfalls füge ich dem c:\utilVerzeichnis eine einfache Cmd / Batch-Datei hinzu, die ungefähr so aussieht:

    @"c:\program files\whereever\foo.exe" %*
    

Dadurch wird im Wesentlichen ein Alias ​​für den Befehl erstellt. Es ist nicht unbedingt perfekt. Einige Programme bestehen wirklich darauf, auf dem Weg zu sein (das ist heutzutage ziemlich selten), und andere Programme, die versuchen, es aufzurufen, finden es möglicherweise nicht richtig. Aber für die meisten Anwendungen funktioniert es gut.

Aber im Allgemeinen musste ich mir keine Sorgen machen, das Hinzufügen von Verzeichnissen zum Pfad zu vermeiden.


Wenn Sie diesem "Pfad" folgen, beachten Sie, dass ein Batch-Skript kein anderes Batch-Skript ohne die Syntax "CALL [bat]" aufrufen kann. Wenn Sie also sicherstellen möchten, dass Ihre weitergeleitete oder nicht weitergeleitete Exe von einer Fledermaus aufgerufen wird, verwenden Sie "call php script.php" anstelle von "php script.php" (was in beide Richtungen funktioniert). Ein ausgezeichneter Grund für die Verwendung. Fledermaus Dispatcher soll Konflikte mit PATH-Namen verhindern (Mehrfachversion derselben Exe)
131

@ 131: Würde es Ihnen etwas ausmachen zu erklären, was Sie mit "diesem" Pfad "meinen? Meinen Sie den bestimmten Dateipfad aus dem Beispiel? Oder eher die allgemeine Methode, die diese Antwort vorschlägt?
ODER Mapper

@ORMapper: Wenn 131 sagt: "Wenn Sie diesem" Pfad "folgen", bedeutet er "Wenn Sie diese Technik anwenden".
Michael Burr

1
Wie Sie geschrieben haben, "finden andere Programme, die versuchen, es aufzurufen, es möglicherweise nicht richtig" - Beispiel: Leider kann es automatische Aufrufe von Befehlszeilenanwendungen auslösen, beispielsweise durch Build-Tools wie NAnt, natürlich. Eine Abhilfe besteht darin, den Befehl mit einem vorangestellten Befehl aufzurufen. Dies bedeutet cmd /cjedoch, dass das Build-Skript Windows-spezifisch wird: / Ich habe dies in einer separaten Frage gestellt .
ODER Mapper

5

Eine andere Idee: Verwenden Sie DIR / X, um die Kurznamen zu ermitteln, die für Nicht-8dot3-Dateinamen generiert wurden. Verwenden Sie diese dann in Ihrem% PATH%.

Zum Beispiel wird 'C: \ Programme' zu 'C: \ PROGRA ~ 1'.


1
Hoppla, ich habe gerade festgestellt, dass dies bereits von @Mitch vorgeschlagen wurde. Ich werde ihm dafür eine +1 geben. :)
Android Eve


2

Ich habe jedes Mal einen Standard-Stream (stdin / stderr / stdout) und ein Exit-Code-PROXY-Programm (genannt Dispatcher https://github.com/131/dispatcher ) geschrieben und verwendet.

Alle CLI-Programme, die ich verwende (Node, PHP, Python, Git, SVN, Rsync, Plink ...), die ich verwende, sind tatsächlich dieselbe Exe-Datei (ca. 10 KB, die ich nur anders benenne), die ich in dieselbe eingefügt habe Verzeichnis. Eine statische Dummy-Klartextdatei führt den "Namen der Proxy-Datei für die echte Exe-Zuordnung" aus.

Der Dispatcher verwendet die Win32-API für die Prozessverwaltung auf niedriger Ebene, um absolut transparent zu sein.

Mit dieser Software habe ich in meinem PATH nur EIN zusätzliches Verzeichnis für alle Programme festgelegt, die ich verwenden könnte.


1

Wenn Sie einen Ordner c: \ bin erstellen, der Ihrem Pfad hinzugefügt wird, und wie Sie sagten, eine Verknüpfung herstellen, kann dies die Zeichenfolge verkürzen. Fügen Sie Systemvariablen möglicherweise eine Variable pf mit dem Wert c: \ Programme hinzu und ersetzen Sie dann c: \ Programme durch% pf% im Pfad.

Bearbeiten:

Erstellen Sie ein virtuelles Laufwerk. subst p: "c: \ Programme"


1
Ich denke, der Pfad würde die erweiterten Variablen enthalten. In diesem Fall würde er nicht kürzer werden.
Ben Voigt

0

Ich folge diesen Schritten, um die Einträge überschaubar zu machen:

  1. Verschiedene Benutzer für unterschiedliche Kombinationen der Verwendung von Softwarepaketen erstellt. Beispiel: (a) Erstellung eines Benutzerwebs zur Bereitstellung der gesamten Webentwicklungssoftware; (b) Erstellung einer Benutzerdatenbank zur Bereitstellung aller Datenbank- und Data Warehousing-Softwarepakete. Denken Sie daran, dass einige Software möglicherweise mehr als einen Eintrag erstellt. Oder manchmal teile ich dies in oracle-spezifische und MSSQL-spezifische und oracle-spezifische Benutzer auf. Ich habe MySQL / PostgreSQL, Tomcat, Wamp, Xamp alle in das Benutzerkonto-Web eingefügt.

  2. Wenn möglich, installieren Sie gängige Pakete wie Office, Photoshop usw. als systemspezifisch für alle Benutzer und spezielle Pakete als benutzerspezifisch. Natürlich musste ich mich bei verschiedenen Benutzern anmelden und diese installieren. Möglicherweise bietet nicht jede Software diese Option. Wenn die Option "Nur für diesen Benutzer installieren" nicht verfügbar ist, installieren Sie sie für das gesamte System.

  3. Ich vermeide die Installation von Programmen im Ordner Programmdatei (x86) oder in der Programmdatei. Ich installiere immer im Basisverzeichnis. Zum Beispiel geht MySQL 64-Bit in den Ordner "C: \ mysql64" und MySQL 32-Bit in den Ordner "C: \ mysql". Ich gehe immer davon aus, dass nur für 64-Bit-Software ein Suffix 64 hinzugefügt wird. Wenn kein Suffix vorhanden ist, handelt es sich um ein 32-Bit. Ich folge dem gleichen zu Java und anderen. Auf diese Weise wird mein Pfad kürzer, ohne "C: \ Program File (x86)". Bei einigen Programmen muss die Konfigurationsdatei möglicherweise bearbeitet werden, um anzuzeigen, wo genau sich die EXE-Datei befindet. In diesem Ordner wird nur das Programm installiert, das in "C: \ Program File (x86)" installiert werden muss. Ich erinnere mich immer daran, die Namen zu kürzen. Ich vermeide Versionsnummern wie tomcat / release / version-2.5.0.3 solche Details. Wenn ich die bekannte Version brauche, Ich erstelle eine Datei nach Namen und lege sie in den Tomcat-Ordner. Im Allgemeinen verkürzen Sie den Link so weit wie möglich.

  4. Fügen Sie einen Stapel hinzu, um den abgekürzten Link zum Pfad zu ersetzen, wenn alle oben genannten Schritte das Windows-Limit überschritten haben.

Melden Sie sich dann bei einem benutzungsspezifischen Benutzer (mobile Anwendung oder Datenbank- / Data Warehousing oder Webentwicklung .. ..) an und führen Sie die entsprechenden Aufgaben aus.

Sie können auch virtuelle Fenster in Fenstern erstellen. Solange Sie über eine lizenzierte Betriebssystemkopie verfügen, können mehrere virtuelle Fenster mit demselben Schlüssel erstellt werden. Sie können Pakete, die für eine bestimmte Aufgabe spezifisch sind, in diesen Computer einfügen. Sie müssen jedes Mal eine separate VM starten. Einige speicherintensive Pakete wie 3D-Animationsfilmer sollten alle auf dem Hauptcomputer und nicht auf der VM installiert werden, da für die VM nur ein Teil des Arbeitsspeichers zur Verfügung steht. Es ist jedoch mühsam, jede VM zu starten.


0

Die oben genannten Lösungen funktionieren nur, wenn Sie Ihren Weg kürzen können. In meinem Fall war das nicht wirklich eine Option, und es war mühsam, jedes Mal, wenn ich eine Eingabeaufforderung öffnete, ein Skript ausführen zu müssen. Deshalb habe ich ein einfaches Skript geschrieben, das beim Öffnen der Eingabeaufforderung automatisch ausgeführt wird und den Inhalt einer Textdatei an Ihren Pfad anfügt.

Es gibt auch einige Kontexte, in denen das Ausführen dieses Skripts Probleme verursacht (z. B. in einer Github- oder Cygwin-Shell). Daher habe ich eine Datei hinzugefügt, die eine Liste von Pfaden enthält, bei denen die Pfadvariable nicht lautet, wenn die Eingabeaufforderung in ihnen gestartet wird Wird nicht über das Startskript geändert, das normalerweise den Pfad aktualisiert.

@echo off

:: Modify these to the actual paths of these two files
set dontSetupFile=C:\Users\Yams\Dontsetup.txt
set pathFile=C:\Users\Yams\Path.txt

:: Retrieve the current path (for determining whether or not we should append to our path)
set curDir=%cd%

:: Be done if the current path is listed in the dontSetupFile
SetLocal EnableDelayedExpansion
for /F "delims=" %%i in (%dontSetupFile%) do (
    if "%%i"=="%curDir%" GOTO AllDone
)



:: Append the pathFile to our current PATH
set pathAppend=
for /F "delims=" %%i in (%pathFile%) do (set pathAppend=!pathAppend!%%i)

set PATH=%PATH%;%pathAppend%


:: The only way to actually modify a command prompt's path via a batch file is by starting
::   up another command prompt window. So we will do this, however, if this script is
::   automatically called on startup of any command prompt window, it will infinately 
::   recurse and bad things will happen.

:: If we already ran, we are done
if "%yams%"=="onion" GOTO AllDone

:: Otherwise, flag that we just ran, and then start up a new command prompt window
::   with this flag set
set yams=onion

cmd \K set PATH=%PATH%;

:: When that command prompt exits, it will load back up this command prompt window, and
::   then the user will need to exit out of this as well. This causes this window to
::   automatically exit once the cmd it just spawned is closed.
exit()

:: Path is set up, we are done!
:AllDone
@echo on

Und Path.txt wird ungefähr so ​​aussehen

C:\Program Files (x86)\Google\google_appengine;
C:\Program Files (x86)\ATI Technologies\ATI.ACE\Core-Static;
C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;
C:\Program Files\Microsoft SQL Server\110\Tools\Binn;
C:\Program Files\Microsoft DNX\Dnvm;
C:\Program Files (x86)\Windows Kits\8.0\Windows Performance Toolkit;

Während Dontsetup.txt so aussehen wird

C:\Program Files (x86)\Windows Kits\8.0\Windows Performance Toolkit
C:\Program Files (x86)\Git\cmd
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin

Um dies beim Start automatisch auszuführen, öffnen Sie regedit, navigieren Sie zu HKEY_LOCAL_MACHINE / SOFTWARE / Microsoft / Command Processor, klicken Sie mit der rechten Maustaste auf die rechte Maustaste und drücken Sie new -> Multi-String Value. Nennen Sie es AutoRun. Setzen Sie den Wert auf

C:\Users\Yams\setUpPath.bat

oder wo immer Sie die Batch-Datei oben gespeichert haben.


0

Haben Sie es nicht versucht, aber wird es funktionieren, PATH in Teile zu teilen und sie in der endgültigen Variablen zu verbinden?

Beispiel: Nehmen wir zunächst an, Sie haben so etwas wie

PATH={LONGPATH1};{LONGPATH2};....{2048th char}....{LONGPATH_N-1};{LONGPATH_N}

Stattdessen erstellen Sie:

_PATH1 = {LONGPATH1};{LONGPATH2};....{2048 char}
_PATH2 = {2049th char}...{LONGPATH_N-1};{LONGPATH_N}
rem // may be more parts
PATH = %_PATH1%;%_PATH2%
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.