Mengapa Windows tidak dapat menangani variabel lingkungan di Path?

44

Kolega saya dan saya memiliki workstation Dell yang identik dengan Windows XP Professional x64 edition yang diinstal.

Variabel lingkungan Path saya dimulai dengan:

%JAVA_HOME%\bin;...

Variabel Path kolega saya menyertakan direktori yang sama, ditentukan menggunakan variabel lingkungan yang sama, tetapi itu bukan item pertama di Path-nya.

Jika saya mengakses properti sistem -> variabel lingkungan dan mengubah nilai variabel JAVA_HOME saya, versi java ditemukan dari perubahan baris perintah seperti yang saya harapkan. Ini memulai jendela konsol baru, untuk memastikan untuk mengambil perubahan.

Tetapi pada mesin rekan saya, tidak. Dia terus menemukan versi Java-nya yang sebelumnya sampai dia memunculkan variabel Path-nya dan menyimpannya (bahkan jika dia tidak mengubahnya). (Sekali lagi, ini adalah saat memulai jendela konsol baru.)

Saya telah mengamati inkonsistensi ini pada Windows selama sekitar 6 bulan sekarang dan sangat ingin tahu tentang itu. Kami memiliki terlalu banyak versi Windows di kantor kami, jadi jarang saya memiliki kesempatan untuk melihat ini terjadi pada dua mesin yang menjalankan versi OS yang sama persis, sampai sekarang.

Apa yang menyebabkan ini? Mengapa mesinnya tidak mengevaluasi ulang Path, menggunakan JAVA_HOME yang baru, ketika milik saya melakukannya?

(Apakah itu karena itu bukan hal pertama di Path? Jika demikian, bagaimana mungkin, dan mengapa? Saya akan melakukan lebih banyak tes untuk memeriksa, tapi saya pikir dia sudah muak dengan itu dan ingin kembali bekerja. .)

skiphoppy
sumber
9
Untuk semua kalian memilih untuk menutup (3 saat ini) ... jika ada dup di suatu tempat, komentar menunjuk saya ke itu pasti akan baik. Jika itu bukan penipuan ... maka katakan padaku apa yang menurut Anda salah dengan pertanyaan ini juga akan menyenangkan.
skiphoppy
1
Mungkin karena lebih pertanyaan sistem dari satu pemrograman, meskipun memiliki dampak langsung pada pemrograman, itu sebabnya saya tidak memilih untuk menutupnya ... :)
9
Attenion close-nazis: Saya ingin mempromosikan pandangan bahwa jika sebuah pertanyaan sesuai pada Stack Overflow sebelum superuser.com dan serverfault.com tiba, maka itu masih sesuai hari ini. Ini pertanyaan pemrograman.
skiphoppy
Apakah maksud Anda programmer hanya pengguna Windows, yang mungkin memiliki masalah ini? Diam, programmer-nazi! Kedua, sebelum situs tanya jawab yang lebih tepat tiba, Anda tidak punya pilihan untuk mengirim pertanyaan di sini. Keramahtamahan SO haruslah bukan argumen untuk menyalahgunakannya.
Val
Saya melihat ini di Windows 10 - substitusi variabel ke PATH gagal sebentar - sebentar untuk bekerja. Pergi ke Variabel Lingkungan & hemat (tanpa perubahan) dan kemudian membuka prompt CMD baru menyelesaikan masalah.
Thomas W

Jawaban:

37

Jalur Anda adalah gabungan dari jalur sistem yang diikuti oleh jalur pengguna. Selain itu, variabel lingkungan sistem mungkin tidak mengandung referensi ke variabel lingkungan pengguna, dan referensi semacam itu tidak akan diperluas. Untuk mendapatkan hasil yang diinginkan, masukkan referensi ke% JAVA_HOME% di PATH variabel lingkungan pengguna , atau buat variabel seperti itu jika belum ada.

Mungkin contoh yang disederhanakan akan membuat ini lebih jelas. Misalkan lingkungan SISTEM adalah

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

dan lingkungan Pengguna JSmith adalah

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

maka jalan yang dihasilkan akan menjadi

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

seperti yang diinginkan.

JPaget
sumber
3
Sistem saya memiliki beberapa variabel pengguna dengan nama yang sama dengan beberapa variabel sistem. Echoing PATH tidak akan memperluas mereka - setelah membaca ini, saya menghapus variabel pengguna duplikat karena saya bertanya-tanya apakah mereka diambil dengan didahulukan (tetapi tidak dapat diperluas). Ini sekarang bekerja untuk saya - terima kasih banyak. :)
Michael
Apakah ada cara melalui Powershell untuk mendapatkan PATH asli yang tidak diperluas? Saya berharap untuk menambahkan PATH saya sambil menjaga variabel lingkungan yang tidak dikembangkan di dalamnya.
CMCDragonkai
Mengatasinya dengan bantuan dari pertanyaan lain. Tulis skrip powershell untuk menangani ini: gist.github.com/CMCDragonkai/a02d77c2d7c0799dd42fd2aab26a3cd5
CMCDragonkai
16

Periksa di registri Windows di bawah kunci ini:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SessionManager\Environment

JIKA variabel lingkungan perlu diperluas (di sini:% JAVA_HOME%)

maka variabel harus ditetapkan sebagai nilai REG_EXPAND_SZ .

Jika menggunakan reg.exe melalui baris perintah untuk menambah / mengedit nilai registri, standarnya adalah untuk ketik REG_SZ. Tentukan jenis REG_EXPAND_SZ dengan menggunakan reg add /t REG_EXPAND_SZopsi.

Climenole
sumber
ya ... ini adalah salah satu pengaturan yang sepertinya saya selalu lupa ... sial registri ;-)
Eddie B
9

Ada masalah yang pasti dengan memperluas variabel lingkungan dalam variabel PATH ketika variabel tersebut diperluas ke jalur yang berisi spasi.

Kami membuat variabel tingkat sistem kami sendiri seperti "OUR_ROOT = c: \ MyRoot" dan kemudian menggunakannya dalam sistem PATH seperti "PATH =;% OUR_ROOT% \ bin;" dan itu akan diperluas dengan benar ke "PATH =; c: \ MyRoot \ bin;". Sejauh ini tidak ada masalah.

Tapi, pada Windows 7 (32-bit), saya punya produk menginstal sendiri dan membuat variabel lingkungan sistem seperti ini:

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

dan itu menambahkannya ke variabel sistem PATH:

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

Tetapi nilai PATH yang ditunjukkan dalam CMD berisi "% STUDIO_BIN%;" dan bukan jalur yang diperluas. Nilai di My Computer> Properties> Advanced> Env.Vars tetap tidak diperluas juga. Ini berarti saya tidak bisa menjalankan program yang memerlukan DLL di direktori itu.

Dengan hanya mengubah STUDIO_BIN (via My Computer> Properties> Advanced ...> Env Vars) ke nama tanpa spasi yang disematkan:

STUDIO_BIN=C:\ProductName\bin

dan kemudian me-restart jendela CMD, PATH sekarang:

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

Solusi lain adalah cukup mengedit variabel sistem yang Anda gunakan dalam PATH menggunakan My Computer> Properties> Advanced ...> dialog Variabel Lingkungan. Saya mencoba menambahkan karakter dan menghapusnya untuk membuat 'perubahan' dan kemudian OK'd keluar, memulai prompt CMD baru dan PATH TIDAK diperluas dengan benar. Saya kemudian mencoba menghapus bagian dari jalan itu

STUDIO_BIN=C:\Program Files\Company Name

(menghilangkan "Nama Produk 10.4") dan lihat, dan CMD prompt berikutnya menunjukkan PATH dengan STUDIO_BIN diperluas dengan benar!

Anehnya, jika saya masuk kembali dan menambahkan "Nama Produk 10.4" ke STUDIO_BIN (termasuk semua ruang yang awalnya ada sebelum saya mulai mucking dengan itu) dan PATH MASIH diperluas dengan benar.

Terbukti dengan perubahan yang cukup pada isinya, variabel PATH menjalani beberapa pemrosesan ekstra dalam dialog Variabel Lingkungan yang memungkinkannya berfungsi. Pemrosesan yang tidak dilakukan ketika variabel ditambahkan oleh penginstal produk (yang mungkin hanya memodifikasi PATH dalam registri secara langsung).

Saya hampir positif ini adalah masalah dengan XP juga. Itu hanya muncul kembali untuk saya di Windows 7 karena saya sedang menyusun mesin pengembangan baru. Ternyata itu belum diperbaiki oleh Microsoft.

Tampaknya bahkan variabel yang didefinisikan MS seperti% ProgramFiles% tidak akan berkembang dengan benar di PATH.

Halaman ini memberikan jawaban yang mungkin jika Anda mengatur PATH melalui file baris perintah atau. (Lampirkan seluruh perintah setelah SET dalam tanda kutip.) Saya tidak tahu apa installer produk yang saya instal digunakan untuk mengatur variabel lingkungan, tetapi ternyata berkeliling pengolahan apa pun yang diperlukan untuk memperluas jalur dengan spasi.

Jadi - untuk meringkas, Anda dapat:

  • ubah jalur (dan pindahkan semua file terkait) ke jalur tanpa spasi, atau

  • sunting variabel yang gagal berkembang dalam dialog Variabel Lingkungan (cukup ubah agar mereka memproses dengan benar - saya tidak yakin berapa banyak yang cukup).

RobDavenport
sumber
7

Saya menanyakan hal ini di forum Microsoft pada bulan Maret 2009, dan tidak pernah menyelesaikannya:

Bagaimana cara menggunakan% ProgramFiles% dalam variabel lingkungan Path? :


Saya mencoba menambahkan folder ke variabel lingkungan Path sistem.

saya ingin menambahkan % ProgramFiles% \ SysInternals

ke variabel jalur yang ada:

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 \

Jadi saya pergi ke tempat di mana Anda mengeditnya:

teks alternatif

Dan saya menambahkan variabel saya ke path:

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

Kemudian membuka jendela command prompt baru variabel lingkungan tidak diganti dengan nilai aktualnya:

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

Yang bisa Anda lihat di screenshot berikut:

teks alternatif


Tetapi untuk menjawab pertanyaan Anda: saya tidak tahu. Sepertinya itu tidak bisa dilakukan.

Ian Boyd
sumber
5

ada dua level variabel lingkungan, global dan pengguna. Jika ia memiliki% Java_home% ditetapkan sebagai variabel lingkungan pengguna tetapi sebaliknya mengubah yang global, ia tidak akan melihat perbedaan.

Sekhat
sumber
2

Pastikan tidak ada spasi di PATH ketika Anda mendefinisikan variabel lingkungan pengguna Anda sendiri. misalnya: C: \ GNAT \ bin; C: \ GNAT \ termasuk tidak akan berfungsi, karena ruang antara ";" dan "C: \ GNAT \ include".

Nij
sumber
2

Tambahkan variabel lingkungan saat masuk ke sesi / konsol menggunakan MSTSC.

Nyalakan ulang mesin dan Anda akan menemukan variabel lingkungan Anda telah bertahan.

Tampaknya ada kekhasan dalam O / S tergantung pada bagaimana Anda terhubung ke mesin ketika Anda mencoba untuk mengubah variabel lingkungan.

Justin
sumber
1

Ini mungkin terkait dengan fitur "ekspansi variabel lingkungan tertunda" (atau ketiadaan), atau mungkin Anda dapat memanfaatkan fitur ini untuk selalu memiliki solusi yang benar.

dari prompt cmd

set /? 

dan baca bagian yang menjelaskan "ekspansi variabel lingkungan tertunda", yang mencakup contoh kecil untuk diuji

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

Jika Anda tidak mendapatkan garis gema, maka itu mungkin menjelaskannya ...

Namun, jika Anda memulai cmd.exe Anda dengan opsi / V, maka Anda dapat menggunakan "!" bukannya "%", yang mengubah behaivior

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

Bagi saya (berjalan di XP), skrip 1 tidak berfungsi, tetapi versi kedua berhasil (dengan cmd.exe / V)

Libjack
sumber
1

Saya memiliki masalah yang sama, dan saya tahu cara memperbaikinya, lumpuh.

Cukup edit PATH Anda lagi, tetapi jangan ubah, dan simpan kembali PATH. Untuk beberapa alasan ini menyebabkan semua referensi variabel lingkungan bersarang untuk dievaluasi kembali.

Jika tidak berhasil lakukan beberapa kali lagi, entah bagaimana itu berhasil sendiri.

BAP
sumber
1

Saya percaya apa yang Windows gagal untuk memperluas variabel dalam PATH karena ia berpikir apa yang belum didefinisikan. Mempertimbangkan:

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

Hipotesis ini sesuai dengan pengamatan saya yang lain - menambahkan %ProgramFiles%\Somethingkepada pengguna PATH akan selalu menghasilkan perluasan yang diharapkan %ProgramFiles%, mengingat hal itu telah didefinisikan dalam lingkungan mesin pada saat pemberitahuan perubahan variabel (karena urutan pemuatan - MESIN dan kemudian PENGGUNA). Tetapi ketika Anda memodifikasi lingkungan mesin, ekspansi variabel yang benar hanya terjadi pada saat boot (sekarang saya tidak tahu bagaimana dan mengapa ini tidak terjadi secara teratur).

pengguna539484
sumber
1

Anda harus mempertimbangkan urutan variabel yang ditetapkan saat login. Jika Anda mencoba menggunakan variabel sebelum diatur, itu akan keluar sebagai string kosong.

PATH yang efektif adalah gabungan dari variabel PATH pengguna diikuti oleh variabel PATH global.

Variabel pengguna ditetapkan sebelum variabel global, jadi Anda tidak bisa menggunakan variabel global dalam variabel PATH pengguna Anda. Selain itu, variabel diatur dalam urutan abjad, sehingga Anda tidak dapat menggunakan variabel yang diurutkan sebelum PATH.

(Setidaknya ini berlaku untuk Windows 7. Saya belum mengujinya pada versi yang lebih baru.)

crickrick
sumber
0

Mungkin Anda salah melakukannya?

Saya mencoba dengan Windows XP Pro SP3 (32bit). Saya memiliki jalur dengan beberapa kemunculan %JAVA_HOME%(dan %JAVAFX_HOME%, dll.). Saya pergi ke baris perintah, ketik PATH, saya melihat variabel diperluas. Baik.

Saya mengubah nilai JAVA_HOME. Kembali ke jendela baris perintah yang sama, PATHsekali lagi, nilai yang sama ... seperti yang diharapkan (berdasarkan pengalaman!).

Saya membuka jendela baris perintah baru, ketik PATH, gotcha, saya melihat nilai baru.

Tidak yakin apa mekanisme yang tepat di sana, tetapi tampaknya semua program yang berjalan, termasuk cmd.exe, menangkap nilai variabel lingkungan saat mulai, dan tidak menoleh ke belakang ... (walaupun saya percaya program yang berperilaku baik dapat dengarkan perubahan env, meskipun tidak terlalu yakin).

Mungkin dilihat sebagai fitur atau bug atau gangguan, tetapi begitulah cara kerjanya. Hei, setidaknya, tidak seperti Win9X kali, kita tidak perlu me-reboot komputer! Dan tidak seperti waktu NT (IIRC), Anda tidak perlu keluar dan kembali.

Mengapa tidak konsisten? Cara-cara Microsoft tidak dapat dipahami ... :-P

PhiLho
sumber
Ini bukan. Setelah perubahan, kami menguji di jendela perintah baru. Kami menyadari fakta bahwa mengubah nilai sistem tidak mengubah nilai untuk menjalankan proses.
skiphoppy
OK, maka 'mungkin' ... :-) Dan penjelasan saya tidak mencakup ketidakkonsistenan, tetapi mungkin berguna bagi beberapa pemula ...: -PI sebagian besar ingin menunjukkan bahwa ekspansi variabel berfungsi di mana-mana di jalan. .. untuk beberapa sistem! (semua yang saya gunakan ... selalu 32bit).
0

Saya telah menyelesaikan pengaturan variabel lingkungan di Sistem> Pengaturan Lanjut> Variabel Lingkungan .

Ada dua panel, variabel Pengguna dan Global (pengguna adalah nama pengguna Windows Anda) dan Variabel Sistem adalah variabel Global, jadi jika Anda menetapkan 'Baru' dari variabel Pengguna, seperti JAVA_HOMEdan meletakkan jalur Anda di bawah, Anda akan menetapkan variabel bahkan jika jalur global Anda memiliki file program di dalam folder.

thunder_nemesis
sumber