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


122

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

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

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

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


5
powershell을 사용하면 상당히 간단 합니다. stackoverflow.com/questions/714877/… . cmd를 사용하면 확실하지 않습니다. 어떻게 든 레지스트리를 수정하거나 .net 어셈블리를 가져와야 할 수 있습니다.
Austen Holmes 2011

1
내가 말했듯이 자바 애플리케이션 내에서이 작업을 수행해야합니다. 난 그냥 cmd를 명령 useng 자바의 실행 생각Runtime.getRuntime().exec("my command");
vale4674

답변:


43

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

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

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

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

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


1
예, JNI 레지스트리 클래스를 사용합니다. 더 큰 문제는 앱이 상승 된 상태로 실행되지 않는다는 것입니다. 그렇게 만드는 방법을 알고 있습니까? 앱의 작은 부분 만 상승 된 상태로 실행하려는 경우 (즉,이 변경을 수행하기 위해) 가장 간단한 솔루션은 작업을 수행하는 매우 간단한 C ++ 앱이며 앱 매니페스트로 표시된 다음 별도의 프로세스로 실행됩니다. UAC 대화 상자를 유발합니다.
David Heffernan 2011

1
HKEY_CURRENT_USER\Environment고도 요구 사항을 피하기 위해 편집 할 수도 있습니다 .
kichik 2011

@David Heffernan 그렇습니다. 그래서 당신의 제안은 C ++ 응용 프로그램을 작성하고 내 Java 응용 프로그램에서 실행하는 것입니까? 이 작업을 수행하는 방법에 대한 예제 코드 또는 링크를 제공 할 수 있습니까?
vale4674

네. David가 말한 것처럼. 오직 당신 만이 상승하지 않습니다. 또한 이것이 현재 사용자에 대해서만 환경을 수정한다는 점을 언급해야합니다.
kichik 2011

시스템 PATH를 수정할 때 UAC 대화 상자 만 강제로 표시하려면이를 별도의 프로세스로 분리해야합니다. 몇 가지 레지스트리 읽기 및 쓰기와 SendMessage가있는 간단한 C ++ 앱만 있으면됩니다. 설정 requestedExecutionLevelrequireAdministrator응용 프로그램 매니페스트한다.
David Heffernan 2011

145

당신이 사용할 수있는:

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"살펴보면 새 값을 볼 수 있습니다.


2
setx사용자 경로 대신 컴퓨터의 경로를 변경하는 데 사용할 수 있는 방법이 있습니까?
Corey Ogburn 2013 년

4
에서 여기 당신이 그것을 사용하여 현재 로그인 한 사용자를위한 그러나 기계뿐만 아니라 변수를 설정할 수있을 말할 수 /m그래도 난 그것을 시도하지 않은 윈도우가 XP에서 명령의 끝에서, 7.
panny

1
setx"기본 옵션은 '2'시간 이상 허용되지 않습니다."명령을 실행할 때 오류가 발생 했습니다. 우회하는 방법은 무엇입니까?
Nam G VU

12
@KilgoreCod 주석 : 명령을 사용하지 않도록주의합니다. 요즘 많은 (대부분?) 설치에서 PATH 변수가 길어집니다. setx는 저장된 문자열을 1024 바이트로 자르고 잠재적으로 PATH를 손상시킬 수 있습니다 (여기에서 논의 참조 superuser.com/ q / 812754 ).
beresfordt

2
나는 이미 1200 바이트가 넘는 경로를 에코하려고합니다. setx 대신 다른 방법이 있습니까?
lawphotog

37

명령 사용에주의

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

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

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


9

이 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/


4

참고로 코드를 통해 경로를 변경하는 방법을 검색하는 사람을 위해 다음 웹 페이지에서 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


레지스트리를 수정해야합니다. 또한 Integer에 대한 캐스트가 좋지 않습니다. 64 비트 호환성을 위해 대신 LPARAM으로 캐스트하십시오.
David Heffernan


4

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

  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.

3

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

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


질문을 읽으십시오. 다시.
jiggunjer

대본. 핫키를 사용하지만 스크립트를 추가하기 위해 어떻게 또는 무엇을해야하는지 모르겠습니다. 도움을 제공하거나 링크를 제공하거나 수행해야 할 작업을 설명 할 수 있습니까?
jwzumwalt
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.