Comment éviter de surcharger la variable d'environnement PATH dans Windows?


115

Je voudrais savoir quelles sont les approches que vous utilisez pour gérer les exécutables de votre système. Par exemple, j'ai presque tout accessible via la ligne de commande, mais maintenant j'arrive à la limite de la chaîne de chemin, donc je ne peux plus ajouter de dir.

Alors que recommandez-vous? Il y a longtemps, j'ai essayé d'utiliser les softLinks des exécutables dans un Dir qui appartenait au chemin, mais cette approche n'a pas fonctionné. Lancer le "exécutable uniquement" vers un Dir connu, a les problèmes que presque toutes les applications nécessitent un ensemble de fichiers, donc c'est également mauvais. Jetez l'exécutable et tous ses fichiers dans un Dir connu, mmm cela fonctionnera, mais la possibilité d'obtenir un conflit dans le nom des fichiers est très très élevée. Créer un HardLink? Je ne sais pas. Qu'est-ce que tu penses?


pourquoi utilisez-vous autant de chemins? path est généralement utilisé pour le répertoire commun, lorsque votre application doit partager étendre object / app / lib avec d'autres. Utilisez tellement pour que l'application démarre plus lentement. Pouvez-vous donner plus de détails sur la façon dont vous utilisez, create path environment var?
pinichi

1
salut pinichi, eh bien, beaucoup d'applications utilisent le standard "C: \ Program File \ AppNAme \ ...", et dans mon cas, beaucoup de ces applications peuvent fonctionner en ligne de commande ou doivent être accessibles à d'autres applications ( par exemple les exécutables de Miktex que n'importe quel éditeur Tex s'attend à ce qu'ils existent), ils doivent donc être dans le PATH. Je ne veux pas connaître une meilleure approche car la mienne n'est pas durable
mjsr

1
Cet outil compressera les chemins. Le résultat est impressionnant: uweraabe.de/Blog/2014/09/09/the-garbled-path-variable/#more-337
InTheNameOfScience

Réponses:


84

Une façon dont je peux penser est d'utiliser d'autres variables d'environnement pour stocker des chemins partiels; par exemple, si vous avez

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

alors vous pouvez créer une nouvelle variable d'environnement telle que

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

après quoi vos chemins originaux deviennent

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

EDIT: Une autre option consiste à créer un binrépertoire contenant les .batfichiers qui pointent vers les .exefichiers appropriés .

EDIT 2: Le commentaire de Ben Voigt sur une autre réponse mentionne que l'utilisation d'autres variables d'environnement comme suggéré pourrait ne pas réduire la longueur de %PATH%car elles seraient développées avant d'être stockées. Cela peut être vrai et je ne l'ai pas testé. Une autre option consiste cependant à utiliser des formulaires 8dot3 pour des noms de répertoire plus longs, par exemple, cela C:\Program Fileséquivaut généralement à C:\PROGRA~1. Vous pouvez utiliser dir /xpour voir les noms plus courts.

EDIT 3: Ce simple test me porte à croire que Ben Voigt a raison.

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

À la fin de cela, vous voyez la sortie hellohelloplutôt que byehello.

EDIT 4: Si vous décidez d'utiliser des fichiers batch pour éliminer certains chemins %PATH%, vous pourriez être préoccupé par la façon de transmettre les arguments de votre fichier batch à votre exécutable afin que le processus soit transparent (c'est-à-dire que vous ne remarquerez aucune différence entre l'appel du fichier batch et l'appel de l'exécutable). Je n'ai pas beaucoup d'expérience dans l'écriture de fichiers batch, mais cela semble fonctionner correctement.

@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%

En règle générale, vous devez être prudent lorsque vous exécutez des fichiers de commandes à partir d'Internet, car vous pouvez faire toutes sortes de choses avec des fichiers de commandes, comme le formatage de votre disque dur. Si vous ne faites pas confiance au code ci-dessus (que j'ai écrit), vous pouvez le tester en remplaçant la ligne

%actualdir%\%actualfile% %args%

avec

echo %actualdir%\%actualfile% %args%

Idéalement, vous devez savoir exactement ce que fait chaque ligne avant de l'exécuter.


1
le formulaire 8dot3 fonctionne bien, mais pour les répertoires vraiment gros, ce n'est pas trop grand, par exemple "C: \ Program Files (x86) \ Microsoft Visual Studio 2008 SDK \ VisualStudioIntegration \ Tools \ Sandcastle \ ProductionTools \". Une autre chose qui économisait un peu était qu'en tant qu'utilisateur, je pouvais créer une variable PATH basée dans le chemin système et ajouter n'importe quel autre Dir. Toutes ces approches sont du type "compacter cette chaîne", mais pouvons-nous avoir un répertoire centralisé de binaires, comme Unix?
mjsr

1
Hmm, en ce qui concerne les répertoires très longs, je pense que le contraire est vrai: plus le répertoire est long, plus vous enregistrez de caractères en utilisant le format 8dot3. S'il est difficile de naviguer cmd, notez que vous pouvez utiliser *pour enregistrer la saisie. Par exemple, à partir de la racine, saisissez dir /x pro*. Vous y verrez votre répertoire souhaité avec son nom 8dot3. Ensuite, utilisez cdpour y accéder et répétez le processus.
Mitch Schwartz

1
En ce qui concerne UNIX, voici ce $PATHqui fonctionne de manière très similaire à %PATH%Windows, donc je ne suis pas sûr de votre point de vue. Par convention, les noms de répertoires UNIX ont tendance à être plus courts que dans Windows et, par conséquent, ont $PATHégalement tendance à être plus courts.
Mitch Schwartz

2
Merci Mitch, le Edit 4 que vous fournissez est ce que je voulais !, maintenant je peux avoir un dossier centralisé avec tous les binaires dont j'ai besoin. Je vais tester plus en profondeur pour voir s'il y a un problème avec une application
mjsr

2
Votre section 'edit 4' est trop compliquée pour passer des arguments à l'exécutable. Voir la réponse de Michael Burr.
Dave Andersen

83

Cela analysera votre variable d'environnement% PATH% et convertira chaque répertoire en son équivalent de nom court, puis le reconstituera:

@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!

Prenez la sortie et mettez à jour la variable PATH dans les variables d'environnement.


Merci qui a été très utile !! Cela a raccourci mon chemin de 1990 à 1338 et tout fonctionne toujours comme un charme! J'ai choisi votre approche car je voulais tout garder sur mon chemin et la liaison sur des fichiers batch aurait pris trop de temps. MERCI!
ndrizza

2
Cela a également été utile car il me parlait de tous les répertoires inexistants dans mon chemin qui s'étaient accumulés au fil du temps.
Nate Glenn

27
Rapid Environment Editor est une autre façon de faire cela. Il met en évidence les répertoires inexistants et dispose d'une option "convertir un long chemin en court".
Russell Gallop

3
@RussellGallop: c'est, monsieur, un outil formidable.
elo80ka

1
Notez le devis de clôture manquant après %%~sa . J'ai essayé de mettre à jour la réponse mais cela ne me laissera pas sauf si je change 6 caractères
zr870

28

si vous utilisez Windows Vista ou version ultérieure, vous pouvez créer un lien symbolique vers le dossier. par exemple:

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

ferait un lien de même c:\pfque votre program filesdossier. J'ai rasé 300 caractères de mon chemin en utilisant cette astuce.


C'est une bonne alternative à l'utilisation d'une variable d'environnement pour représenter un chemin partiel.
porcus

1
Cela aiderait certainement plus, mais si vous souhaitez une solution plus «correcte» (prise en charge?), Vous pouvez remplacer les instances de c:\Program Fileset c:\Program Files (x86)par les variables prédéfinies %ProgramFiles%et %ProgramFiles(x86)% tenforums.com/tutorials/ ... Celles-ci ne sauvegardent que quelques caractères chacune , mais si vous êtes VRAIMENT sur le point de maximiser PATH, cela pourrait faire la différence. Pour cette question, je vais créer% pf% et% pfx% qui résolvent les chemins corrects. Merci pour l'idée! :)
rainabba

Le problème avec l'utilisation de variables telles que% pf% et% pfx% est que vous rencontrez les mêmes problèmes que la création de liens symboliques - les mises à jour logicielles peuvent ajouter à nouveau des éléments à la variable de chemin. L'autre problème avec l'utilisation de variables comme celles-ci est qu'il n'est pas rapide et facile de créer des scripts autour de celles-ci ou de les parcourir à partir de l'explorateur. En utilisant la méthode que j'ai décrite, vous pouvez littéralement ouvrir c: \ PF. Windows le voit comme un dossier afin que vous puissiez également écrire une chauve-souris ou un powershell assez facilement.
bmg002

10

Au cas où quelqu'un serait intéressé ...

Je trouve que je n'ai jamais vraiment besoin de tous ces chemins à la fois, donc je crée un tas de fichiers batch "d'initialisation" qui modifient le chemin en conséquence.

Par exemple, si je voulais faire du développement C ++ dans Eclipse, je ferais:

> initmingw
> initeclipse
> eclipse

Ceci est également pratique pour éviter les conflits entre les exécutables du même nom (comme les compilateurs C ++ et D, qui ont tous deux un make.exe).

Mes fichiers batch ressemblent généralement à ceci:

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

Je trouve cette approche relativement propre et je n'ai pas encore rencontré de problèmes avec elle.


7

Je n'ai généralement pas à m'inquiéter à ce sujet (je n'ai pas rencontré de limite de taille de chemin - je ne sais même pas ce que c'est sur les systèmes Windows modernes), mais voici ce que je pourrais faire pour éviter de mettre le répertoire d'un programme dans le chemin:

  • la plupart des utilitaires de ligne de commande sont lancés dans un c:\utilrépertoire qui se trouve sur le chemin
  • sinon, j'ajouterai un simple fichier cmd / batch dans le c:\utilrépertoire qui ressemble à quelque chose comme:

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

qui crée essentiellement un alias pour la commande. Ce n'est pas forcément parfait. Certains programmes insistent vraiment pour être dans le chemin (c'est assez rare de nos jours), et d'autres programmes qui essaient de l'invoquer pourraient ne pas le trouver correctement. Mais pour la plupart des utilisations, cela fonctionne bien.

Mais en général, je n'ai pas eu à me soucier d'éviter d'ajouter des répertoires au chemin.


Lorsque vous commencez à suivre ce "chemin", sachez qu'un script batch ne peut pas appeler un autre script batch sans la syntaxe "CALL [bat]". Donc, si vous voulez vous assurer que votre exe transféré ou non est appelé à partir d'une chauve-souris, utilisez "call php script.php" au lieu de simplement "php script.php" (qui fonctionne dans les deux sens) Une excellente raison d'utiliser. le répartiteur de batte est d'éviter les conflits de noms de PATH (version multiple du même exe)
131

@ 131: Pourriez-vous expliquer ce que vous entendez par «ce« chemin »»? Voulez-vous dire le chemin de fichier particulier de l'exemple? Ou plutôt la méthode générale suggérée par cette réponse?
OR Mapper

@ORMapper: quand 131 dit, 'Quand vous commencez à suivre ce "chemin", il veut dire, "Quand vous utilisez cette technique".
Michael Burr

1
Comme vous l'avez écrit, "d'autres programmes qui essaient de l'invoquer pourraient ne pas le trouver correctement" - exemple: Malheureusement, il peut lancer des appels automatiques vers des applications en ligne de commande, par exemple en construisant des outils tels que NAnt, bien sûr. Un remède consiste à appeler la commande avec un préfixe cmd /c, mais cela signifie à son tour que le script de construction devient spécifique à Windows: / J'ai posé une question à ce sujet dans une question distincte .
OR Mapper

5

Une autre idée: utilisez DIR / X pour déterminer les noms courts générés pour les noms de fichiers non-8dot3. Ensuite, utilisez-les dans votre% PATH%.

Par exemple, «C: \ Program Files» devient «C: \ PROGRA ~ 1».


1
Oups, je viens de réaliser que cela avait déjà été suggéré par @Mitch. Je vais lui donner un +1 pour ça. :)
Android Eve


2

J'ai écrit et utilisé à chaque fois un flux standard (stdin / stderr / stdout) et un programme de code de sortie PROXY (appelé dispatcher https://github.com/131/dispatcher )

Tous les programmes CLI que j'utilise (node, php, python, git, svn, rsync, plink ...) que j'utilise sont en fait le même fichier exe (environ 10 ko, que je nomme différemment), que j'ai mis dans le même annuaire. Un fichier de texte en clair statique factice effectue le "mappage du nom du fichier proxy vers un véritable exe".

Dispatcher utilise l'API Win32 de gestion des processus de bas niveau pour être absolument transparent.

En utilisant ce logiciel, je n'ai qu'un seul répertoire supplémentaire défini dans mon PATH pour tous les programmes que je pourrais utiliser.


1

Créer un dossier c: \ bin en ajoutant à votre chemin et en établissant des liens fixes comme vous l'avez dit pourrait raccourcir la chaîne. Ajoutez peut-être une variable pf aux variables système avec la valeur c: \ Program Files, puis remplacez c: \ Program Files par% pf% dans le chemin.

Éditer:

Créez un lecteur virtuel. subst p: "c: \ program files"


1
Je pense que le chemin contiendrait les variables développées, auquel cas il ne serait pas plus court.
Ben Voigt

0

Je suis ces étapes pour rendre les entrées gérables:

  1. Création de différents utilisateurs pour différentes combinaisons d'utilisation de progiciels. Exemple: (a) Création d'un site Web utilisateur pour rendre disponible tous les logiciels de développement Web; b) Création d’une base de données d’utilisateurs pour rendre disponibles tous les progiciels de base de données et d’entreposage de données. N'oubliez pas que certains logiciels peuvent créer plusieurs entrées. Ou parfois, je divise cela en utilisateurs spécifiques à l'oracle et à MSSQL et aux utilisateurs spécifiques à l'oracle. J'ai mis MySQL / PostgreSQL, tomcat, wamp, xamp tous dans le compte utilisateur webr.

  2. Si possible, installez des packages communs tels que office, photoshop, .. en tant que système spécifique disponible pour tous les utilisateurs et des packages spéciaux en fonction de l'utilisateur. Bien sûr, j'ai dû me connecter à différents utilisateurs et les installer. Tous les logiciels ne proposent pas cette option. Si l'option "installer pour cet utilisateur uniquement" n'est pas disponible, installez-la pour l'ensemble du système.

  3. J'évite d'installer des programmes dans le dossier Program File (x86) ou dans Program File. J'installe toujours dans le répertoire de base. Par exemple, MySQL 64 bits va dans "C: \ mysql64" et MySQL 32 bits va dans le dossier "C: \ mysql". Je suppose toujours d'ajouter un suffixe 64 uniquement pour les logiciels 64 bits. Si aucun suffixe, alors c'est un 32 bits. Je suis la même chose pour Java et d'autres. De cette façon, mon chemin sera plus court, sans inclure "C: \ Program File (x86)". Pour certains logiciels, le fichier de configuration devra peut-être être modifié pour afficher exactement l'emplacement du fichier .exe. Seul le programme qui demande à être installé dans "C: \ Program File (x86)" sera installé dans ce dossier. Je me souviens toujours de raccourcir les noms. J'évite le numéro de version comme tomcat / release / version-2.5.0.3 de tels détails. Si j'ai besoin de la version connue, Je crée un fichier par version de nom et le mets dans le dossier tomcat. En général, raccourcissez le lien autant que possible.

  4. Incluez n'importe quel lot pour remplacer le lien abrégé vers le chemin, si toutes les étapes ci-dessus ont dépassé la limite de Windows.

Connectez-vous ensuite à l'utilisateur spécifique à l'utilisation (application mobile, ou base de données / entreposage de données ou développement Web .. ..) et effectuez les tâches appropriées.

Vous pouvez également créer des fenêtres virtuelles dans les fenêtres. Tant que vous disposez d'une copie du système d'exploitation sous licence, la création de plusieurs fenêtres virtuelles avec la même clé est possible. Vous pouvez placer des packages spécifiques pour une tâche particulière sur cette machine. Vous devez lancer une VM distincte à chaque fois. Certains packages gourmands en mémoire tels que les réalisateurs de films d'animation 3D doivent tous être placés dans la machine principale, pas dans la machine virtuelle car la machine virtuelle n'aura qu'une partie de la RAM disponible pour son utilisation. Cependant, il est difficile de démarrer chaque machine virtuelle.


0

Les solutions ci-dessus ne fonctionnent que si vous pouvez réduire votre chemin. Dans mon cas, ce n'était pas vraiment une option, et c'était compliqué de devoir exécuter un script à chaque fois que j'ouvrais une invite de commande. J'ai donc écrit un script simple qui s'exécute automatiquement lors de l'ouverture de l'invite de commande et ajoute le contenu d'un fichier texte à votre chemin.

Il y a aussi des contextes où l'exécution de ce script casse les choses (par exemple, dans un shell github ou cygwin), donc j'ai également ajouté un fichier contenant une liste de chemins qui, si l'invite de commande est lancée dans ceux-ci, la variable de chemin est n 'pas changé via le script de démarrage qui met normalement à jour le chemin.

@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

Et Path.txt ressemblera à quelque chose comme

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;

Alors que Dontsetup.txt ressemblera à quelque chose comme

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

Pour que cela s'exécute automatiquement au démarrage, ouvrez regedit, accédez à HKEY_LOCAL_MACHINE / SOFTWARE / Microsoft / Command Processor, puis cliquez avec le bouton droit sur la droite et appuyez sur nouveau -> Valeur multi-chaînes. Nommez-le AutoRun. Définissez sa valeur sur

C:\Users\Yams\setUpPath.bat

ou partout où vous avez stocké le fichier de commandes ci-dessus.


0

Je n'ai pas essayé, mais le fractionnement de PATH en parties fonctionnera-t-il et les joignera-t-il dans le travail final des variables?

Exemple d'abord, disons que vous avez quelque chose comme

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

Au lieu de cela, vous créez:

_PATH1 = {LONGPATH1};{LONGPATH2};....{2048 char}
_PATH2 = {2049th char}...{LONGPATH_N-1};{LONGPATH_N}
rem // may be more parts
PATH = %_PATH1%;%_PATH2%
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.