Pourquoi Windows ne peut-il gérer une variable d'environnement dans Path?

Mon collègue et moi avons des postes de travail Dell identiques avec l'édition Windows XP Professional x64 installée.

La variable d'environnement My Path commence par:

%JAVA_HOME%\bin;... 

La variable Path de mon collègue comprend le même répertoire, spécifié en utilisant la même variable d'environnement, mais ce n'est pas le premier élément de son chemin.

Si j'adhère les propriétés du système -> variables d'environnement et change la valeur de ma variable JAVA_HOME, la version de java trouvée à partir de la ligne de commande change comme je l'espère. Ceci démarre une toute nouvelle fenêtre de console, pour être sûr de reprendre les modifications.

Mais sur la machine de mon collègue, ce n'est pas le cas. Il continue de trouver sa version précédente de Java jusqu'à ce qu'il affiche sa variable Path et l'enregistre (même s'il ne modifie pas cela). (Encore une fois, c'est à l'ouverture d'une nouvelle fenêtre de console).

J'ai observé cette incohérence sur Windows depuis environ 6 mois maintenant et très curieux à ce sujet. Nous avons beaucoup trop de versions de Windows dans notre bureau, et j'ai rarement eu l'occasion de voir cela se produire sur deux machines exécutant la même version du système d'exploitation, jusqu'à maintenant.

Qu'est-ce qui cause cela? Pourquoi sa machine ne réévalue-t-elle pas Path, en utilisant le nouveau JAVA_HOME, lorsque le mien fait?

(Est-ce parce que ce n'est pas la première chose dans le chemin? Si oui, comment cela pourrait-il être et pourquoi? Je ferais plus de tests pour vérifier, mais je pense qu'il en a déjà marre et qu'il veut retourner au travail .)

Votre chemin est la concaténation du chemin du système suivi du chemin de l'utilisateur. De plus, les variables d'environnement système peuvent ne pas contenir de références aux variables d'environnement utilisateur et aucune de ces références ne sera étendue. Pour obtenir le résultat souhaité, insérez la référence à% JAVA_HOME% dans la variable d'environnement de l' utilisateur PATH, ou créez une telle variable si elle n'existe pas déjà.

Peut-être qu'un exemple simplifié rendra-t-il cela plus clair. Supposons que l'environnement SYSTEM soit

 ProgramFiles = C:\Program Files SystemRoot = C:\WINDOWS PATH = %SystemRoot%\SYSTEM32 

Et l'environnement de l'utilisateur JSmith est

 JAVA_HOME = %ProgramFiles%\Java\bin USERPROFILE = C:\USERS\JSmith PATH = %JAVA_HOME%\bin;%USERPROFILE%\bin 

Alors la voie qui en résulterait serait

 C:\WINDOWS\SYSTEM32;C:\Program Files\Java\bin;C:\Users\JSmith\bin 

comme voulu.

Vérifiez dans le registre Windows sous cette clé:

 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SessionManager\Environment 

SI la variable d'environnement doit être développée (ici:% JAVA_HOME%)

Alors la variable doit être définie comme une valeur REG_EXPAND_SZ .

Si vous utilisez reg.exe via la ligne de commande pour ajouter / modifier les valeurs de registre, il par défaut tapez REG_SZ. Spécifiez le type REG_EXPAND_SZ en utilisant l'option reg add /t REG_EXPAND_SZ .

Il existe un problème certain avec l'expansion des variables d'environnement dans la variable PATH lorsque la variable s'étend à un chemin qui contient des espaces.

Nous avons créé nos propres variables de niveau système comme "OUR_ROOT = c: \ MyRoot", puis l'avons utilisé dans le système PATH comme "PATH =;% OUR_ROOT% \ bin;" Et cela se développe correctement dans "PATH =; c: \ MyRoot \ bin;". Jusqu'à présent, aucun problème.

Mais, sur Windows 7 (32 bits), j'ai installé un produit lui-même et créé des variables d'environnement système comme ceci:

 STUDIO_BIN=C:\program files\Company Name\Product Name 10.4\bin 

Et il l'a ajouté à la variable PATH système:

 PATH=<other path elements>;%STUDIO_BIN%;<more path elements> 

Mais les valeurs PATH indiquées dans CMD contiennent "% STUDIO_BIN%;" Et non le chemin élargi. La valeur dans Poste de travail> Propriétés> Avancé> Env.Vars est restée non étendue. Cela signifiait que je ne pouvais pas exécuter des programmes nécessitant une DLL dans ce répertoire.

En changeant simplement STUDIO_BIN (via Poste de travail> Propriétés> Avancé …> Env Vars) à un nom sans espaces incorporés:

 STUDIO_BIN=C:\ProductName\bin 

Puis redémarrez la fenêtre CMD, le PATH est maintenant:

 PATH=<other path elements>;C:\ProductName\bin;<more path elements> 

Une autre solution est de modifier suffisamment la variable système que vous utilisez dans le PATH en utilisant la boîte de dialogue Poste de travail> Propriétés> Avancé …> Variables d'environnement. J'ai essayé d'ajouter un caractère et de le supprimer pour faire un 'changement', puis j'ai terminé, j'ai commencé une nouvelle invite CMD et PATH n'a PAS été correctement développé. J'ai ensuite essayé de supprimer une partie du chemin, donc c'était

 STUDIO_BIN=C:\Program Files\Company Name 

(En omettant "Product Name 10.4") et lo, et voici, la prochaine invite CMD a montré PATH avec STUDIO_BIN correctement développé!

Curieusement, si je suis retourné et ajouté le "Nom du produit 10.4" à STUDIO_BIN (y compris tous les espaces qui étaient à l'origine là avant que je commence à se fouler avec lui) et PATH était toujours correctement étendu.

Évidemment, avec suffisamment de changements dans son contenu, la variable PATH subit un traitement supplémentaire dans la boîte de dialogue Variables d'environnement qui lui permet de fonctionner. Le traitement n'est pas fait lorsque la variable a été ajoutée par l'installateur du produit (qui a probablement simplement modifié PATH dans le registre directement).

Je suis presque positif. C'était aussi un problème avec XP. Il a juste refait surface pour moi dans Windows 7 alors que je préparais une nouvelle machine de développement. Apparemment, Microsoft n'a pas été corrigé.

Apparemment, même les variables définies par MS comme% ProgramFiles% ne se développeront pas correctement dans le PATH.

Cette page fournit une réponse possible si vous définissez PATH via la ligne de commande ou le fichier batch. (Ensemble de la commande entière après SET entre guillemets.) Je ne sais pas quel installateur le produit que j'ai installé utilisé pour définir les variables d'environnement, mais évidemment, il a évolué quel que soit le traitement nécessaire pour étendre correctement les chemins avec des espaces.

Donc – pour résumer, vous pouvez:

  • Modifier les chemins (et déplacer tous les fichiers associés) vers des chemins sans espaces, ou

  • Modifiez les variables qui ne se développent pas dans la boîte de dialogue Variables d'environnement (en les modifiant suffisamment pour qu'elles puissent être correctement traitées – je ne suis pas positif, combien cela suffit).

J'ai demandé cela sur les forums de Microsoft en mars 2009 et je ne l'ai jamais résolu:

Comment utiliser% ProgramFiles% dans la variable d'environnement Path? :


J'essaie d'ajouter un dossier à la variable d'environnement Path du système.

Je veux ajouter % ProgramFiles% \ SysInternals

À la variable de chemin existante:

C: \ PROGRA ~ 1 \ Borland \ Delphi5 \ Projects \ Bpl; C: \ PROGRA ~ 1 \ Borland \ Delphi5 \ Bin; % SystemRoot% \ system32; % SystemRoot% ;% SystemRoot % \ System32 \ Wbem; C: \ Program Files \ Microsoft SQL Server \ 80 \ Tools \ BINN; C: \ Program Files \ Microsoft SQL Server \ 80 \ Tools \ Binn \; C: \ Program Files \ Microsoft SQL Server \ 90 \ Tools \ binn \; C: \ Program Files \ Microsoft SQL Server \ 90 \ DTS \ Binn \; C: \ Program Files \ Microsoft SQL Server \ 90 \ Tools \ Binn \ VSShell \ Common7 \ IDE \; C: \ Program Files \ Microsoft Visual Studio 8 \ Common7 \ IDE \ PrivateAssemblies \;% SYSTEMROOT % \ System32 \ WindowsPowerShell \ v1.0 \

Donc je vais au lieu où vous l'éditez:

Texte alt

Et j'ajoute ma variable au chemin:

% ProgramFiles % \ SysInternals; C: \ PROGRA ~ 1 \ Borland \ Delphi5 \ Projects \ Bpl; (couper)

Ensuite, ouvrir une nouvelle fenêtre d'invite de commande, la variable d'environnement n'est pas remplacée par sa valeur réelle:

Path =% ProgramFiles % \ SysInternals; C: \ PROGRA ~ 1 \ Borland \ Delphi5 \ Projects \ Bpl (snip)>

Ce que vous pouvez voir dans la capture d'écran suivante:

Texte alt


Mais pour répondre à votre question: je ne sais pas. On dirait qu'il ne peut pas être fait.

Il existe deux niveaux de variables d'environnement, globales et utilisateurs. S'il a% Java_home% défini comme une variable d'environnement utilisateur, mais qu'il change plutôt le global, il ne verra aucune différence.

Assurez-vous qu'il n'y a pas d'espaces dans le PATH lorsque vous définissez vos propres variables d'environnement utilisateur. Par exemple: C: \ GNAT \ bin; C: \ GNAT \ include ne fonctionne pas, en raison de l'espace entre le ";" Et "C: \ GNAT \ include".

Ajouter les variables d'environnement tout en vous connectant à la session / console en utilisant MSTSC.

Redémarrez la machine et vous verrez que votre environnement aura persisté.

Il semble y avoir un coup de foudre dans l'O / S selon la façon dont vous avez été connecté à la machine lorsque vous avez tenté de modifier la variable d'environnement.

Il pourrait être lié à la fonctionnalité "expansion différée de l'environnement différé" (ou à l'absence de celui-ci), ou peut-être que vous pouvez profiter de cette fonctionnalité pour toujours avoir une solution correcte.

À partir d'une invite cmd

 set /? 

Et lisez la section décrivant "expansion de l'environnement différée", qui comprend un petit exemple pour tester

 set VAR=before if "%VAR%" == "before" ( set VAR=after if "%VAR%" == "after" @echo If you see this, it worked ) 

Si vous n'obtenez pas la ligne d'écho, alors cela pourrait l'expliquer …

Si, cependant, vous démarrez votre cmd.exe avec / V option, alors vous pouvez utiliser "!" Au lieu de "%", qui change le comportement

 set VAR=before if "%VAR%" == "before" ( set VAR=after if "!VAR!" == "after" @echo If you see this, it worked ) 

Pour moi (en cours d'exécution sur XP), le 1er script n'a pas fonctionné, mais la deuxième version a eu (avec cmd.exe / V)

J'ai eu le même problème, et je sais comment réparer, c'est boiteux.

Il suffit de modifier votre PATH à nouveau, mais ne changez pas et ré-sauvegardez PATH. Pour une raison quelconque, toutes les références de variables d'environnement imbriquées doivent être réévaluées.

Si cela ne fonctionne pas, faites-en encore quelques fois, d'une manière ou d'une autre, cela fonctionne simplement.

Peut-être que vous le faites mal?

J'ai essayé avec Windows XP Pro SP3 (32 bits). J'ai un chemin avec plusieurs occurrences de %JAVA_HOME% (et %JAVAFX_HOME% , etc.). Je vais à la ligne de commande, tapez PATH , je vois les variables étendues. Bien.

Je change la valeur de JAVA_HOME . Retour à la même fenêtre de ligne de commande, PATH nouveau, même valeur … comme prévu (par expérience!).

J'ouvre une nouvelle fenêtre de ligne de commande, tapez PATH , gotcha, je vois la nouvelle valeur.

Je ne sais pas quel est le mécanisme exact là-bas, mais il semble que tout programme en cours d'exécution, y compris cmd.exe, capture les valeurs des variables d'environnement à l'heure de début et ne regarde pas en arrière … (même si je crois qu'un programme bien comporté peut Écoutez les changements env, pas trop sûr cependant).

Cela peut être considéré comme une caractéristique ou un bug ou un ennui, mais c'est comme ça qu'il fonctionne. Hé, au moins, contrairement aux temps Win9X, nous n'avons pas à redémarrer l'ordinateur! Et contrairement aux temps de NT (IIRC), vous ne devez pas vous déconnecter et le retourner.

Pourquoi l'incohérence? Les façons de Microsoft sont impénétrables … 😛

PATH est la concaténation de la variable PATH utilisateur suivie de la variable PATH globale. Pour utiliser une variable dans un autre, le premier doit déjà être défini. Les variables utilisateur sont définies avant les variables globales (au moins ici sur mon Windows 7 64 bits), vous ne pouvez donc pas utiliser les variables globales dans votre variable PATH utilisateur. En outre, les variables sont définies dans l'ordre alphabétique, donc vous devez également garder cela à l'esprit.

Je crois que Windows échoue à étendre une variable dans PATH parce qu'elle pense à ce qu'elle n'est pas encore définie. Considérer:

 REM Ensure variable is undefined SET UNDEFINED= REM And then try to expand it ECHO UNDEFINED=%UNDEFINED% 

Cette hypothèse est conforme à mon autre observation – en ajoutant %ProgramFiles%\Something aux utilisateurs PATH entraînera toujours une expansion attendue de %ProgramFiles% , étant donné qu'il a été défini dans l'environnement machine au moment de la notification de changement variable (ordre de chargement dû – MACHINE Puis UTILISATEUR). Mais lorsque vous modifiez l'expansion de la variable correcte de l'environnement de la machine, cela se produit au démarrage (en ce moment, je n'ai aucune idée de comment et pourquoi cela ne se produit pas régulièrement).

J'ai résolu de définir les variables d'environnement dans Système> Paramètres avancés> Variables d'environnement .

Il existe deux panneaux, les variables utilisateur et globales (l'utilisateur est votre nom d'utilisateur Windows) et les variables système sont des variables globales, donc, si vous définissez 'Nouveau' à partir de variables utilisateur, telles que JAVA_HOME et placez votre chemin ci-dessous, vous définirez des variables même si votre système global Le chemin d'accès comporte des fichiers de programme dans un dossier.