[java] Windows 명령 줄에서 PATH 변수를 영구적으로 업데이트하는 방법은 무엇입니까?

내가 실행하면 set PATH=%PATH%;C:\\Something\\bin명령 줄에서 ( cmd.exe) 한 후 실행 echo %PATH%내가 PATH에 추가 된이 문자열을 참조하십시오. 명령 줄을 닫고 열면 새 문자열이 PATH에 없습니다.

현재 프로세스뿐만 아니라 향후 모든 프로세스에 대해 명령 줄에서 PATH를 영구적으로 업데이트하려면 어떻게해야합니까?

시스템 속성 → 고급 → 환경 변수로 이동하여 PATH를 업데이트하고 싶지 않습니다.

이 명령은 Java 응용 프로그램에서 실행해야합니다 (다른 질문 참조 ).



답변

이를 수행하는 방법에 대한 문서는 MSDN 에서 찾을 수 있습니다 . 핵심 추출은 다음과 같습니다.

프로그래밍 방식으로 시스템 환경 변수를 추가하거나 수정하려면 HKEY_LOCAL_MACHINE \ System \ CurrentControlSet \ Control \ Session Manager \ Environment 레지스트리 키에 추가 한 다음 WM_SETTINGCHANGElParam이 문자열 “Environment”로 설정된 메시지 를 브로드 캐스트합니다 . 이를 통해 셸과 같은 응용 프로그램이 업데이트를 선택할 수 있습니다.

이 키를 수정하려면 애플리케이션에 높은 관리자 권한이 필요합니다.

사용자 별 환경 만 수정해도 좋다고 의견에 표시합니다. HKEY_CURRENT_USER \ Environment 의 값을 편집하여이를 수행하십시오 . 이전과 마찬가지로 WM_SETTINGCHANGE메시지 를 브로드 캐스트해야 합니다.

JNI 레지스트리 클래스를 사용하여 Java 애플리케이션에서 쉽게이 작업을 수행 할 수 있어야합니다.


답변

당신이 사용할 수있는:

setx PATH "%PATH%;C:\\Something\\bin"

그러나 setx저장된 문자열을 1024 바이트로 잘라 PATH를 손상시킬 수 있습니다.

/M변경됩니다 PATHHKEY_LOCAL_MACHINE대신 HKEY_CURRENT_USER. 즉, 사용자 대신 시스템 변수입니다. 예를 들면 :

SETX /M PATH "%PATH%;C:\your path with spaces"

새 PATH는 현재 cmd.exe.

그러나 레지스트리 또는 새 항목 cmd.exe"set p"살펴보면 새 값을 볼 수 있습니다.


답변

명령 사용에주의

setx PATH "%PATH%;C:\Something\bin"

구현의 “기능”때문에 PATH 변수를 수정합니다. 요즘 많은 (대부분?) 설치에서 변수가 길어질 setx것입니다. 저장된 문자열을 1024 바이트로 자르고 잠재적으로 PATH를 손상시킬 수 있습니다 ( 여기 에서 논의 참조 ).

( 저는 특별히이 문제를 신고하기 위해 가입했기 때문에 ’12 년 5 월 2 일에 게시 된 답변에 직접 댓글을 달 수있는 사이트 평판이 부족합니다. 이러한 댓글을 추가해 주신 분들께 감사드립니다. )


답변

이 Python-script [*]는 정확히 다음을 수행합니다.

"""
Show/Modify/Append registry env-vars (ie `PATH`) and notify Windows-applications to pickup changes.

First attempts to show/modify HKEY_LOCAL_MACHINE (all users), and
if not accessible due to admin-rights missing, fails-back
to HKEY_CURRENT_USER.
Write and Delete operations do not proceed to user-tree if all-users succeed.

Syntax:
    {prog}                  : Print all env-vars.
    {prog}  VARNAME         : Print value for VARNAME.
    {prog}  VARNAME   VALUE : Set VALUE for VARNAME.
    {prog}  +VARNAME  VALUE : Append VALUE in VARNAME delimeted with ';' (i.e. used for `PATH`).
    {prog}  -VARNAME        : Delete env-var value.

Note that the current command-window will not be affected,
changes would apply only for new command-windows.
"""

import winreg
import os, sys, win32gui, win32con

def reg_key(tree, path, varname):
    return '%s\%s:%s' % (tree, path, varname)

def reg_entry(tree, path, varname, value):
    return '%s=%s' % (reg_key(tree, path, varname), value)

def query_value(key, varname):
    value, type_id = winreg.QueryValueEx(key, varname)
    return value

def yield_all_entries(tree, path, key):
    i = 0
    while True:
        try:
            n,v,t = winreg.EnumValue(key, i)
            yield reg_entry(tree, path, n, v)
            i += 1
        except OSError:
            break ## Expected, this is how iteration ends.

def notify_windows(action, tree, path, varname, value):
    win32gui.SendMessage(win32con.HWND_BROADCAST, win32con.WM_SETTINGCHANGE, 0, 'Environment')
    print("---%s %s" % (action, reg_entry(tree, path, varname, value)), file=sys.stderr)

def manage_registry_env_vars(varname=None, value=None):
    reg_keys = [
        ('HKEY_LOCAL_MACHINE', r'SYSTEM\CurrentControlSet\Control\Session Manager\Environment'),
        ('HKEY_CURRENT_USER', r'Environment'),
    ]
    for (tree_name, path) in reg_keys:
        tree = eval('winreg.%s'%tree_name)
        try:
            with winreg.ConnectRegistry(None, tree) as reg:
                with winreg.OpenKey(reg, path, 0, winreg.KEY_ALL_ACCESS) as key:
                    if not varname:
                        for regent in yield_all_entries(tree_name, path, key):
                            print(regent)
                    else:
                        if not value:
                            if varname.startswith('-'):
                                varname = varname[1:]
                                value = query_value(key, varname)
                                winreg.DeleteValue(key, varname)
                                notify_windows("Deleted", tree_name, path, varname, value)
                                break  ## Don't propagate into user-tree.
                            else:
                                value = query_value(key, varname)
                                print(reg_entry(tree_name, path, varname, value))
                        else:
                            if varname.startswith('+'):
                                varname = varname[1:]
                                value = query_value(key, varname) + ';' + value
                            winreg.SetValueEx(key, varname, 0, winreg.REG_EXPAND_SZ, value)
                            notify_windows("Updated", tree_name, path, varname, value)
                            break  ## Don't propagate into user-tree.
        except PermissionError as ex:
            print("!!!Cannot access %s due to: %s" %
                    (reg_key(tree_name, path, varname), ex), file=sys.stderr)
        except FileNotFoundError as ex:
            print("!!!Cannot find %s due to: %s" %
                    (reg_key(tree_name, path, varname), ex), file=sys.stderr)

if __name__=='__main__':
    args = sys.argv
    argc = len(args)
    if argc > 3:
        print(__doc__.format(prog=args[0]), file=sys.stderr)
        sys.exit()

    manage_registry_env_vars(*args[1:])

다음은 setenv.py현재 경로의 어딘가에 있는 파일에 저장되었다고 가정 한 몇 가지 사용 예 입니다. 이 예제 에서는 admin-rights가 없었 으므로 변경 사항은 로컬 사용자의 레지스트리 트리에만 영향을 미쳤습니다.

> REM ## Print all env-vars
> setenv.py
!!!Cannot access HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session   Manager\Environment:PATH due to: [WinError 5] Access is denied
HKEY_CURRENT_USER\Environment:PATH=...
...

> REM ## Query env-var:
> setenv.py PATH C:\foo
!!!Cannot access HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session   Manager\Environment:PATH due to: [WinError 5] Access is denied
!!!Cannot find HKEY_CURRENT_USER\Environment:PATH due to: [WinError 2] The system cannot find the file specified

> REM ## Set env-var:
> setenv.py PATH C:\foo
!!!Cannot access HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session   Manager\Environment:PATH due to: [WinError 5] Access is denied
---Set HKEY_CURRENT_USER\Environment:PATH=C:\foo

> REM ## Append env-var:
> setenv.py +PATH D:\Bar
!!!Cannot access HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session   Manager\Environment:PATH due to: [WinError 5] Access is denied
---Set HKEY_CURRENT_USER\Environment:PATH=C:\foo;D:\Bar

> REM ## Delete env-var:
> setenv.py -PATH
!!!Cannot access HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session   Manager\Environment:PATH due to: [WinError 5] Access is denied
---Deleted HKEY_CURRENT_USER\Environment:PATH

[*] 수정 출처 : http://code.activestate.com/recipes/416087-persistent-environment-variables-on-windows/


답변

참고로 코드를 통해 경로를 변경하는 방법을 검색하는 사람을 위해 다음 웹 페이지에서 Delphi 프로그래머가 작성한 유용한 게시물을 인용하고 있습니다. http://www.tek-tips.com/viewthread.cfm?qid=686382

TonHu (프로그래머) 22 Oct 03 17:57 원본 게시물을 읽은 위치를 찾았습니다.
http://news.jrsoftware.org/news/innosetup.isx/msg02129 ….

필요한 것의 발췌는 다음과 같습니다.

LParam에 “Environment”문자열을 지정해야합니다. Delphi에서는 다음과 같이합니다.

 SendMessage(HWND_BROADCAST, WM_SETTINGCHANGE, 0, Integer(PChar('Environment')));

(ao) InnoSetup의 저자 인 Jordan Russell ( http://www.jrsoftware.org) 이 제안했습니다 ( “Inno Setup은 Windows 프로그램 용 무료 설치 프로그램입니다. 1997 년에 처음 소개 된 Inno Setup은 오늘날 경쟁자이며 기능 세트와 안정성의 상용 설치 프로그램. “) (더 많은 사람들이 InnoSetup을 사용하기를 바랍니다.)

HTH


답변

사용자가 제한된 액세스 권한 만 갖고 휴대용 앱을 사용하는 회사 네트워크에는 다음과 같은 명령 줄 트릭이 있습니다.

  1. 사용자 환경 변수 쿼리 : reg query "HKEY_CURRENT_USER\Environment". "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment"LOCAL_MACHINE에 사용 합니다.
  2. 새 사용자 환경 변수 추가 : reg add "HKEY_CURRENT_USER\Environment" /v shared_dir /d "c:\shared" /t REG_SZ. REG_EXPAND_SZ다른 %% 변수를 포함하는 경로에 사용 합니다.
  3. 기존 환경 변수 삭제 : reg delete "HKEY_CURRENT_USER\Environment" /v shared_dir.

답변

이 스크립트는
http://www.autohotkey.com/board/topic/63210-modify-system-path-gui/

필요에 따라 리팩터링 할 수있는 모든 필수 Windows API 호출이 포함됩니다. 실제로 시스템 PATH를 쉽게 변경하는 것은 AutoHotkey GUI입니다. 관리자로 실행해야합니다.