Tại sao Windows không thể xử lý một biến môi trường trong Đường dẫn?


44

Đồng nghiệp của tôi và tôi đã cài đặt máy trạm Dell giống hệt với phiên bản Windows XP Professional x64.

Biến môi trường Đường dẫn của tôi bắt đầu bằng:

%JAVA_HOME%\bin;...

Biến Đường dẫn của đồng nghiệp của tôi bao gồm cùng một thư mục, được chỉ định sử dụng cùng một biến môi trường, nhưng nó không phải là mục đầu tiên trong Đường dẫn của anh ta.

Nếu tôi truy cập các thuộc tính hệ thống -> biến môi trường và thay đổi giá trị của biến JAVA_HOME của tôi, phiên bản java được tìm thấy từ dòng lệnh sẽ thay đổi như tôi mong đợi. Điều này đang bắt đầu một cửa sổ giao diện điều khiển hoàn toàn mới, để chắc chắn nhận các thay đổi.

Nhưng trên máy của đồng nghiệp tôi thì không. Anh ta tiếp tục tìm phiên bản Java trước đó cho đến khi anh ta đưa ra biến Path và lưu nó (ngay cả khi anh ta không thay đổi gì với nó). (Một lần nữa, đây là khi bắt đầu một cửa sổ giao diện điều khiển hoàn toàn mới.)

Tôi đã quan sát sự không nhất quán này trên Windows khoảng 6 tháng nay và rất tò mò về nó. Chúng tôi có quá nhiều phiên bản Windows trong văn phòng của chúng tôi, vì vậy hiếm khi tôi có cơ hội thấy điều này xảy ra trên hai máy chạy cùng một phiên bản HĐH, cho đến bây giờ.

Điều gì gây ra điều này? Tại sao máy của anh ta không đánh giá lại Đường dẫn, sử dụng JAVA_HOME mới, khi máy của tôi không?

. .)


9
Đối với tất cả các bạn đang bỏ phiếu để đóng (3 tại thời điểm này) ... nếu có một bản sao ở đâu đó, một nhận xét chỉ cho tôi chắc chắn sẽ rất hay. Nếu đó không phải là một bản sao ... thì hãy nói cho tôi biết bạn nghĩ gì sai với câu hỏi này cũng sẽ rất hay.
Skiphoppy

1
Có lẽ bởi vì nó là một câu hỏi hệ thống hơn là một câu hỏi lập trình, mặc dù nó có tác động trực tiếp đến lập trình, đó là lý do tại sao tôi không bỏ phiếu để đóng nó ... :)

9
Attenion close-nazis: Tôi muốn quảng bá quan điểm rằng nếu một câu hỏi phù hợp trên Stack Overflow trước khi superuser.com và serverfault.com đến thì ngày nay vẫn còn phù hợp. Đây là một câu hỏi lập trình.
Skiphoppy

Bạn có nghĩa là các lập trình viên chỉ là người dùng Windows, những người có thể có vấn đề này? Im đi, lập trình viên-nazi! Thứ hai, trước khi trang web Hỏi và Đáp thích hợp hơn đến, bạn không có tùy chọn để gửi câu hỏi ở đây. Sự hiếu khách của SO phải không phải là một lý lẽ cho việc lạm dụng nó.
Val

Tôi đang xem xét điều này trong Windows 10 - việc thay thế biến thành PATH không liên tục hoạt động. Chuyển đến Biến môi trường & lưu (không thay đổi) và sau đó mở dấu nhắc CMD mới đã giải quyết vấn đề.
Thomas W

Câu trả lời:


37

Đường dẫn của bạn là nối của đường dẫn hệ thống theo sau là đường dẫn người dùng. Ngoài ra, các biến môi trường hệ thống có thể không chứa tham chiếu đến các biến môi trường người dùng và mọi tham chiếu như vậy sẽ không được mở rộng. Để có kết quả mong muốn, hãy chèn tham chiếu đến% JAVA_HOME% trong biến môi trường người dùng PATH hoặc tạo một biến như vậy nếu nó không tồn tại.

Có lẽ một ví dụ đơn giản sẽ làm cho điều này rõ ràng hơn. Giả sử môi trường HỆ THỐNG là

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

và môi trường của User JSmith là

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

sau đó đường dẫn kết quả sẽ là

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

như mong muốn.


3
Hệ thống của tôi có một số biến env người dùng có cùng tên với một số biến env hệ thống. Echoing PATH sẽ không mở rộng chúng - sau khi đọc nó, tôi đã loại bỏ các biến người dùng trùng lặp vì tôi tự hỏi liệu chúng có được chọn trước hay không (nhưng không thể mở rộng). Điều này bây giờ đã làm việc cho tôi - cảm ơn rất nhiều. :)
Michael

Có cách nào thông qua Powershell để có được bản gốc chưa được mở rộng không? Tôi đã hy vọng nối vào PATH của mình trong khi bảo tồn các biến môi trường chưa được mở rộng trong đó.
CMCDragonkai

Giải quyết nó với một số trợ giúp từ một câu hỏi khác. Viết một tập lệnh powershell để xử lý việc này: gist.github.com/CMCDragonkai/a02d77c2d7c0799dd42fd2aab26a3cd5
CMCDragonkai

16

Kiểm tra sổ đăng ký Windows theo khóa này:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SessionManager\Environment

NẾU biến môi trường cần được mở rộng (ở đây:% JAVA_HOME%)

sau đó biến phải được đặt thành giá trị REG_EXPAND_SZ .

Nếu sử dụng reg.exe thông qua dòng lệnh để thêm / chỉnh sửa giá trị đăng ký, nó mặc định là gõ REG_SZ. Chỉ định loại REG_EXPAND_SZ bằng cách sử dụng reg add /t REG_EXPAND_SZtùy chọn.


vâng ... đây là một trong những cài đặt mà tôi dường như luôn quên ... đăng ký phiền phức ;-)
Eddie B

9

Có một vấn đề nhất định với việc mở rộng các biến môi trường trong biến PATH khi biến mở rộng thành một đường dẫn chứa khoảng trắng.

Chúng tôi đã tạo các biến cấp độ hệ thống của riêng mình như "OUR_ROOT = c: \ MyRoot" và sau đó sử dụng nó trong hệ thống PATH như "PATH =;% OUR_ROOT% \ bin;" và được mở rộng chính xác thành "PATH =; c: \ MyRoot \ bin;". Cho đến nay không có vấn đề.

Nhưng, trên Windows 7 (32-bit), tôi đã có một sản phẩm tự cài đặt và tạo các biến môi trường hệ thống như thế này:

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

và nó đã thêm nó vào biến PATH của hệ thống:

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

Nhưng các giá trị PATH được hiển thị trong CMD chứa "% STUDIO_BIN%;" và không phải là con đường mở rộng. Giá trị trong Máy tính của tôi> Thuộc tính> Nâng cao> Env.Vars vẫn chưa được mở rộng. Điều này có nghĩa là tôi không thể chạy các chương trình yêu cầu DLL trong thư mục đó.

Bằng cách chỉ thay đổi STUDIO_BIN (thông qua Máy tính của tôi> Thuộc tính> Nâng cao ...> Env Vars) thành tên không có khoảng trắng được nhúng:

STUDIO_BIN=C:\ProductName\bin

và sau đó khởi động lại cửa sổ CMD, PATH hiện tại:

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

Một giải pháp khác là chỉnh sửa đầy đủ biến hệ thống bạn đang sử dụng trong PATH bằng hộp thoại Máy tính của tôi> Thuộc tính> Nâng cao ...> Biến môi trường. Tôi đã thử thêm một ký tự và xóa nó để thực hiện 'thay đổi' và sau đó OK, bắt đầu một dấu nhắc CMD mới và PATH KHÔNG được mở rộng chính xác. Sau đó tôi đã cố gắng xóa một phần của đường dẫn để nó được

STUDIO_BIN=C:\Program Files\Company Name

(bỏ qua "Tên sản phẩm 10,4") và lo, và nhắc nhở, dấu nhắc CMD tiếp theo hiển thị PATH với STUDIO_BIN được mở rộng đúng cách!

Thật kỳ lạ, nếu tôi quay lại và thêm "Tên sản phẩm 10,4" vào STUDIO_BIN (bao gồm tất cả các khoảng trống ban đầu ở đó trước khi tôi bắt đầu mấp máy với nó) và PATH được mở rộng chính xác.

Rõ ràng với sự thay đổi đủ về nội dung của nó, biến PATH trải qua một số xử lý bổ sung trong hộp thoại Biến môi trường cho phép nó hoạt động. Việc xử lý không được thực hiện khi biến được thêm bởi trình cài đặt của sản phẩm (có thể chỉ sửa đổi PATH trong sổ đăng ký).

Tôi gần như tích cực đây cũng là một vấn đề với XP. Nó chỉ xuất hiện trở lại với tôi trong Windows 7 khi tôi kết hợp một cỗ máy phát triển mới. Rõ ràng nó đã không được sửa chữa bởi Microsoft.

Rõ ràng ngay cả MS đã xác định các biến như% ProgramFiles% sẽ không mở rộng chính xác trong PATH.

Trang này cung cấp câu trả lời có thể nếu bạn đang đặt PATH thông qua tệp dòng lệnh hoặc tệp bó. .

Vì vậy - để tóm tắt, bạn có thể:

  • thay đổi đường dẫn (và di chuyển tất cả các tệp được liên kết) thành đường dẫn không có dấu cách hoặc

  • chỉnh sửa các biến không mở rộng được trong hộp thoại Biến môi trường (thay đổi chúng đủ để khiến chúng xử lý chính xác - Tôi không tích cực bao nhiêu là đủ).


7

tôi đã hỏi điều này trên các diễn đàn của Microsoft vào tháng 3 năm 2009 và không bao giờ giải quyết được:

Làm cách nào để sử dụng% ProgramFiles% trong biến môi trường Path? :


Tôi đang cố gắng thêm một thư mục vào biến môi trường Đường dẫn của hệ thống.

tôi muốn thêm % ProgramFiles% \ SysIternals

đến biến đường dẫn hiện có:

C: \ PROGRA ~ 1 \ Borland \ Delphi5 \ Project \ 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: \ Tệp chương trình \ Microsoft SQL Server \ 90 \ Tools \ binn \; C: \ Chương trình tập tin \ Microsoft SQL Server \ 90 \ DTS \ Binn \; C: \ Chương trình tập tin \ Microsoft SQL Server \ 90 \ Tools \ Binn \ VSShell \ Common7 \ IDE \; C: \ Program Files \ Microsoft Visual Studio 8 \ Common7 \ IDE \ PrivateAssemblies \;% SYSTEMROOT % \ System32 \ WindowsPowerShell \ v1.0 \

Vì vậy, tôi đi vào nơi bạn chỉnh sửa nó:

văn bản thay thế

Và tôi thêm biến của tôi vào đường dẫn:

% ProgramFiles % \ SysI Internalals; C: \ PROGRA ~ 1 \ Borland \ Delphi5 \ Project \ Bpl; (bắn tỉa)

Sau đó, mở một cửa sổ nhắc lệnh mới, biến môi trường không được thay thế bằng giá trị thực của nó:

Đường dẫn =% Chương trình tệp % \ SysI Internalals; C: \ PROGRA ~ 1 \ Borland \ Delphi5 \ Project \ Bpl (snip)>

Mà bạn có thể thấy trong ảnh chụp màn hình sau:

văn bản thay thế


Nhưng để trả lời câu hỏi của bạn: tôi không biết. Có vẻ như nó không thể được thực hiện.


5

Có hai cấp độ biến môi trường, toàn cầu và người dùng. Nếu anh ta có% Java_home% được đặt làm biến môi trường người dùng nhưng thay vào đó là thay đổi biến toàn cục, anh ta sẽ không thấy bất kỳ sự khác biệt nào.


2

Đảm bảo không có khoảng trắng trong PATH khi bạn xác định các biến môi trường người dùng của riêng bạn. ví dụ: C: \ GNAT \ bin; C: \ GNAT \ bao gồm không hoạt động, vì khoảng cách giữa dấu ";" và "C: \ GNAT \ bao gồm".


2

Thêm các biến môi trường trong khi đăng nhập vào phiên / bảng điều khiển bằng MSTSC.

Khởi động lại máy và bạn sẽ thấy các biến môi trường của bạn sẽ tồn tại.

Dường như có một sự giải quyết trong O / S tùy thuộc vào cách bạn được kết nối với máy khi bạn cố gắng thay đổi biến môi trường.


1

Nó có thể liên quan đến tính năng "mở rộng biến môi trường bị trì hoãn" (hoặc thiếu tính năng này) hoặc có lẽ bạn có thể tận dụng tính năng này để luôn có giải pháp chính xác.

từ một dấu nhắc cmd

set /? 

và đọc phần mô tả "mở rộng biến môi trường bị trì hoãn", bao gồm một ví dụ nhỏ để kiểm tra

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

Nếu bạn không có được dòng echo, thì điều đó có thể giải thích nó ...

Tuy nhiên, nếu bạn bắt đầu cmd.exe với tùy chọn / V, thì bạn có thể sử dụng "!" thay vì "%", thay đổi hành vi

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

Đối với tôi (chạy trên XP), tập lệnh thứ nhất không hoạt động, nhưng phiên bản thứ hai thì có (với cmd.exe / V)


1

Tôi đã có cùng một vấn đề, và tôi biết làm thế nào để khắc phục nó, sự khập khiễng của nó.

Chỉ cần chỉnh sửa lại PATH của bạn, nhưng không thay đổi và lưu lại PATH. Vì một số lý do, điều này khiến tất cả các tham chiếu biến môi trường lồng nhau được đánh giá lại.

Nếu nó không hoạt động, hãy làm điều đó thêm một vài lần nữa, bằng cách nào đó nó sẽ tự hoạt động.


1

Tôi tin rằng những gì Windows không thể mở rộng một biến trong PATH bởi vì nó nghĩ những gì nó chưa được xác định. Xem xét:

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

Giả thuyết này phù hợp với quan sát khác của tôi - thêm %ProgramFiles%\Somethingvào người dùng PATH sẽ luôn dẫn đến việc mở rộng dự kiến %ProgramFiles%, do nó đã được xác định trong môi trường máy tại thời điểm thông báo thay đổi biến đổi (thứ tự tải do - MÁY và sau đó là NGƯỜI DÙNG). Nhưng khi bạn sửa đổi môi trường máy, việc mở rộng biến chính xác chỉ xảy ra vào thời điểm khởi động (ngay bây giờ tôi không biết làm thế nàotại sao điều này không xảy ra trên cơ sở thường xuyên).


1

Bạn phải xem xét thứ tự các biến được đặt khi đăng nhập. Nếu bạn cố gắng sử dụng một biến trước khi nó được đặt, nó sẽ xuất hiện dưới dạng chuỗi trống.

PATH hiệu quả là sự kết hợp của biến PATH của người dùng, theo sau là biến PATH toàn cầu.

Biến người dùng được đặt trước biến toàn cục, vì vậy bạn không thể sử dụng biến toàn cục trong biến PATH của người dùng. Ngoài ra, các biến được đặt theo thứ tự bảng chữ cái, vì vậy bạn không thể sử dụng các biến sắp xếp trước PATH.

(Điều này ít nhất áp dụng cho Windows 7. Tôi chưa thử nghiệm điều này trên các phiên bản mới hơn.)


0

Có lẽ bạn đang làm sai?

Tôi đã thử với Windows XP Pro SP3 (32 bit). Tôi có một con đường với một vài lần xuất hiện %JAVA_HOME%(và %JAVAFX_HOME%, v.v.). Tôi đi đến dòng lệnh, loại PATH, tôi thấy các biến được mở rộng. Tốt

Tôi thay đổi giá trị của JAVA_HOME. Quay lại cùng một cửa sổ dòng lệnh, PATHmột lần nữa, cùng một giá trị ... như mong đợi (theo kinh nghiệm!).

Tôi mở một cửa sổ dòng lệnh mới, gõ PATH, gotcha, tôi thấy giá trị mới.

Không chắc cơ chế chính xác ở đó là gì, nhưng dường như bất kỳ chương trình đang chạy nào, bao gồm cmd.exe, nắm bắt các giá trị của các biến môi trường tại thời điểm bắt đầu và không nhìn lại ... (mặc dù tôi tin rằng một chương trình hoạt động tốt có thể lắng nghe thay đổi env, mặc dù không quá chắc chắn).

Nó có thể được coi là một tính năng hoặc một lỗi hoặc phiền toái, nhưng đó là cách nó hoạt động. Này, ít nhất, không giống như lần Win9X, chúng ta không phải khởi động lại máy tính! Và không giống như thời NT (IIRC), bạn không phải đăng xuất và quay lại.

Tại sao không thống nhất? Những cách của Microsoft không thể hiểu được ... :-P


Đây không phải là nó. Sau khi thay đổi, chúng tôi sẽ thử nghiệm trong một cửa sổ lệnh mới. Chúng tôi nhận thức được thực tế rằng việc thay đổi giá trị hệ thống sẽ không thay đổi giá trị cho các quy trình đang chạy.
Skiphoppy

OK, do đó 'có lẽ' ... :-) Và lời giải thích của tôi không bao hàm sự không nhất quán, nhưng có thể hữu ích với một số người mới ...: -PI chủ yếu muốn chỉ ra rằng mở rộng biến hoạt động ở mọi nơi trên đường dẫn. .. cho một số hệ thống! (tất cả những người tôi đã sử dụng ... luôn là 32 bit).

0

Tôi đã giải quyết cài đặt các biến môi trường trong Hệ thống> Cài đặt nâng cao> Biến môi trường .

Có hai bảng, biến Người dùng và Toàn cầu (người dùng là tên người dùng Windows của bạn) và Biến hệ thống là biến toàn cục, vì vậy nếu bạn đặt 'Mới' từ biến Người dùng, chẳng hạn như JAVA_HOMEvà đặt đường dẫn của bạn bên dưới, bạn sẽ đặt biến ngay cả khi đường dẫn chung của bạn có tập tin chương trình trong thư mục.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.