[PYTHON] 파이썬에서 Windows 환경 변수를 수정하기위한 인터페이스
PYTHON파이썬에서 Windows 환경 변수를 수정하기위한 인터페이스
어떻게하면 Python 스크립트에서 Windows 환경 변수를 지속적으로 수정할 수 있습니까? (setup.py 스크립트입니다)
나는 이것을 위해 사용할 표준 함수 나 모듈을 찾고있다. 나는 이미 그것을하는 레지스트리 방법에 익숙하지만, 그것에 관한 모든 의견도 환영합니다.
해결법
-
==============================
1.setx를 사용하면 몇 가지 단점이 있는데, 특히 환경 변수에 추가하려고 할 때 (예 : setx PATH % Path %; C : \ mypath) 문제가 될 때마다 반복해서 경로에 추가합니다. 더 나쁜 것은 컴퓨터 경로 (HKEY_LOCAL_MACHINE에 저장 됨)와 사용자 경로 (HKEY_CURRENT_USER에 저장 됨)를 구분하지 않습니다. 명령 프롬프트에 표시되는 환경 변수는이 두 값의 연결로 구성됩니다. 그러므로 setx를 호출하기 전에 :
setx를 사용하면 몇 가지 단점이 있는데, 특히 환경 변수에 추가하려고 할 때 (예 : setx PATH % Path %; C : \ mypath) 문제가 될 때마다 반복해서 경로에 추가합니다. 더 나쁜 것은 컴퓨터 경로 (HKEY_LOCAL_MACHINE에 저장 됨)와 사용자 경로 (HKEY_CURRENT_USER에 저장 됨)를 구분하지 않습니다. 명령 프롬프트에 표시되는 환경 변수는이 두 값의 연결로 구성됩니다. 그러므로 setx를 호출하기 전에 :
user PATH == u machine PATH == m %PATH% == m;u > setx PATH %PATH%;new Calling setx sets the USER path by default, hence now: user PATH == m;u;new machine PATH == m %PATH% == m;m;u;new
setx를 호출하여 PATH에 추가 할 때마다 시스템 경로가 % PATH % 환경 변수에 불가피하게 중복됩니다. 이러한 변경 사항은 영구적이며 재부팅에 의해 재설정되지 않으므로 시스템의 수명 기간 동안 누적됩니다.
도스에서 이것을 보완하려고하는 것이 내 능력을 넘어선 다. 그래서 저는 파이썬으로 방향을 돌 렸습니다. 오늘 필자가 제기 한 해결책은 중복을 도입하지 않고 PATH에 추가하는 것을 포함하여 레지스트리를 조정하여 환경 변수를 설정하는 것입니다.
from os import system, environ import win32con from win32gui import SendMessage from _winreg import ( CloseKey, OpenKey, QueryValueEx, SetValueEx, HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, KEY_ALL_ACCESS, KEY_READ, REG_EXPAND_SZ, REG_SZ ) def env_keys(user=True): if user: root = HKEY_CURRENT_USER subkey = 'Environment' else: root = HKEY_LOCAL_MACHINE subkey = r'SYSTEM\CurrentControlSet\Control\Session Manager\Environment' return root, subkey def get_env(name, user=True): root, subkey = env_keys(user) key = OpenKey(root, subkey, 0, KEY_READ) try: value, _ = QueryValueEx(key, name) except WindowsError: return '' return value def set_env(name, value): key = OpenKey(HKEY_CURRENT_USER, 'Environment', 0, KEY_ALL_ACCESS) SetValueEx(key, name, 0, REG_EXPAND_SZ, value) CloseKey(key) SendMessage( win32con.HWND_BROADCAST, win32con.WM_SETTINGCHANGE, 0, 'Environment') def remove(paths, value): while value in paths: paths.remove(value) def unique(paths): unique = [] for value in paths: if value not in unique: unique.append(value) return unique def prepend_env(name, values): for value in values: paths = get_env(name).split(';') remove(paths, '') paths = unique(paths) remove(paths, value) paths.insert(0, value) set_env(name, ';'.join(paths)) def prepend_env_pathext(values): prepend_env('PathExt_User', values) pathext = ';'.join([ get_env('PathExt_User'), get_env('PathExt', user=False) ]) set_env('PathExt', pathext) set_env('Home', '%HomeDrive%%HomePath%') set_env('Docs', '%HomeDrive%%HomePath%\docs') set_env('Prompt', '$P$_$G$S') prepend_env('Path', [ r'%SystemDrive%\cygwin\bin', # Add cygwin binaries to path r'%HomeDrive%%HomePath%\bin', # shortcuts and 'pass-through' bat files r'%HomeDrive%%HomePath%\docs\bin\mswin', # copies of standalone executables ]) # allow running of these filetypes without having to type the extension prepend_env_pathext(['.lnk', '.exe.lnk', '.py'])
현재 프로세스 나 상위 쉘에는 영향을 미치지 않지만 실행 후 열린 모든 cmd 창에 영향을 미치며 재부팅 할 필요가 없으며 복제본을 도입하지 않고도 여러 번 안전하게 편집하고 다시 실행할 수 있습니다.
-
==============================
2.외부 Windows setx 명령을 사용하는 것만 큼 쉽습니다.
외부 Windows setx 명령을 사용하는 것만 큼 쉽습니다.
C:\>set NEWVAR Environment variable NEWVAR not defined C:\>python Python 2.5.4 (r254:67916, Dec 23 2008, 15:10:54) [MSC v.1310 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> import os >>> os.system('setx NEWVAR newvalue') 0 >>> os.getenv('NEWVAR') >>> ^Z C:\>set NEWVAR Environment variable NEWVAR not defined
이제 새 명령 프롬프트를 엽니 다.
C:\>set NEWVAR NEWVAR=newvalue
보시다시피 setx는 현재 세션이나 부모 프로세스 (첫 번째 명령 프롬프트)의 변수를 설정하지 않습니다. 그러나 그것은 미래의 프로세스를 위해 레지스트리에 변수를 지속적으로 설정합니다.
나는 부모 프로세스의 환경을 전혀 바꿀 방법이 없다고 생각한다. (있다면, 나는 그것을 듣고 싶다.).
-
==============================
3.프로그램을 통해 현재 DOS 세션의 환경을 변경하려고 시도한 것은 천년 전이었을 것입니다. 문제는 프로그램이 자체 DOS 셸 내에서 실행되므로 부모 환경에서 작동해야한다는 것입니다. DOS 컨트롤 블록에서 시작하여 메모리 제어 블록 체인을 따라 가면서 해당 부모 환경의 위치를 찾습니다. 일단 이것을 어떻게하는지 알았 더라면, 환경 변수를 조작해야 할 필요성이 사라졌습니다. 아래에서 터보 파스칼 코드를 알려 드리겠습니다. 그러나 트릭을 수행하는 데는 적어도 세 가지 방법이 더 있습니다.
프로그램을 통해 현재 DOS 세션의 환경을 변경하려고 시도한 것은 천년 전이었을 것입니다. 문제는 프로그램이 자체 DOS 셸 내에서 실행되므로 부모 환경에서 작동해야한다는 것입니다. DOS 컨트롤 블록에서 시작하여 메모리 제어 블록 체인을 따라 가면서 해당 부모 환경의 위치를 찾습니다. 일단 이것을 어떻게하는지 알았 더라면, 환경 변수를 조작해야 할 필요성이 사라졌습니다. 아래에서 터보 파스칼 코드를 알려 드리겠습니다. 그러나 트릭을 수행하는 데는 적어도 세 가지 방법이 더 있습니다.
그리고 여기에는 메모리 위치를보고하는 프로그램의 파스칼 코드 (네델란드어 사전과 파스칼 프로그래밍 북이 필요할 수 있음)가 있습니다. 그것은 여전히 우리가 도스 5.00을 실행하고 있다고보고, Windows XP에서 작동하는 것 같습니다. 이것은 단지 시작에 불과하며, 선택된 환경을 조작하기 위해 많은 저수준 프로그래밍이 필요합니다. 포인터 구조가 정확 해 보일 수도 있기 때문에 1994 년의 환경 모델이 요즘에도 여전히 유지되는지 확신 할 수 없습니다 ...
program MCBKETEN; uses dos, HexConv; {----------------------------------------------------------------------------} { Programma: MCBKETEN.EXE } { Broncode : MCBKETEN.PAS } { Doel : Tocht langs de MCB's met rapportage } { Datum : 11 januari 1994 } { Auteur : Meindert Meindertsma } { Versie : 1.00 } {----------------------------------------------------------------------------} type MCB_Ptr = ^MCB; { MCB_PtrPtr = ^MCB_Ptr; vervallen wegens DOS 2.11 -- zie verderop } MCB = record Signatuur : char; Eigenaar : word; Paragrafen : word; Gereserveerd : array[1..3] of byte; Naam : array[1..8] of char; end; BlokPtr = ^BlokRec; BlokRec = record Vorige : BlokPtr; DitSegment, Paragrafen : word; Signatuur : string[6]; Eigenaar, Omgeving : word; Functie : String4; Oorsprong, Pijl : char; KorteNaam : string[8]; LangeNaam : string; Volgende : BlokPtr; end; PSP_Ptr = ^PSP; PSP = record Vulsel1 : array[1..44] of byte; Omgeving : word; Vulsel2 : array[47..256] of byte; end; var Zone : string[5]; ProgGevonden, EindeKeten, Dos3punt2 : boolean; Regs : registers; ActMCB : MCB_Ptr; EersteSchakel, Schakel, LaatsteSchakel : BlokPtr; ActPSP : PSP_Ptr; EersteProg, Meester, Ouder, TerugkeerSegment, TerugkeerOffset, TerugkeerSegment2, OuderSegment : word; Specificatie : string[8]; ReleaseNummer : string[2]; i : byte; {----------------------------------------------------------------------------} { PROCEDURES EN FUNCTIES } {----------------------------------------------------------------------------} function Coda (Omgeving : word; Paragrafen : word) : string; var i : longint; Vorige, Deze : char; Streng : string; begin i := 0; Deze := #0; repeat Vorige := Deze; Deze := char (ptr (Omgeving, i)^); inc (i); until ((Vorige = #0) and (Deze = #0)) or (i div $10 >= Paragrafen); if (i + 3) div $10 < Paragrafen then begin Vorige := char (ptr (Omgeving, i)^); inc (i); Deze := char (ptr (Omgeving, i)^); inc (i); if (Vorige = #01) and (Deze = #0) then begin Streng := ''; Deze := char (ptr (Omgeving, i)^); inc (i); while (Deze <> #0) and (i div $10 < Paragrafen) do begin Streng := Streng + Deze; Deze := char (ptr (Omgeving, i)^); inc (i); end; Coda := Streng; end else Coda := ''; end else Coda := ''; end {Coda}; {----------------------------------------------------------------------------} { HOOFDPROGRAMMA } {----------------------------------------------------------------------------} BEGIN {----- Initiatie -----} Zone := 'Lower'; ProgGevonden := FALSE; EindeKeten := FALSE; Dos3punt2 := (dosversion >= $1403) and (dosversion <= $1D03); Meester := $0000; Ouder := $0000; Specificatie[0] := #8; str (hi (dosversion) : 2, ReleaseNummer); if ReleaseNummer[1] = ' ' then ReleaseNummer[1] := '0'; {----- Pointer naar eerste MCB ophalen ------} Regs.AH := $52; { functie $52 geeft adres van DOS Info Block in ES:BX } msdos (Regs); { ActMCB := MCB_PtrPtr (ptr (Regs.ES, Regs.BX - 4))^; NIET onder DOS 2.11 } ActMCB := ptr (word (ptr (Regs.ES, Regs.BX - 2)^), $0000); {----- MCB-keten doorlopen -----} new (EersteSchakel); EersteSchakel^.Vorige := nil; Schakel := EersteSchakel; repeat with Schakel^ do begin DitSegment := seg (ActMCB^); Paragrafen := ActMCB^.Paragrafen; if DitSegment + Paragrafen >= $A000 then Zone := 'Upper'; Signatuur := Zone + ActMCB^.Signatuur; Eigenaar := ActMCB^.Eigenaar; ActPSP := ptr (Eigenaar, 0); if not ProgGevonden then EersteProg := DitSegment + 1; if Eigenaar >= EersteProg then Omgeving := ActPSP^.Omgeving else Omgeving := 0; if DitSegment + 1 = Eigenaar then begin ProgGevonden := TRUE; Functie := 'Prog'; KorteNaam[0] := #0; while (ActMCB^.Naam[ ord (KorteNaam[0]) + 1 ] <> #0) and (KorteNaam[0] < #8) do begin inc (KorteNaam[0]); KorteNaam[ ord (KorteNaam[0]) ] := ActMCB^.Naam[ ord (KorteNaam[0]) ]; end; if Eigenaar = prefixseg then begin TerugkeerSegment := word (ptr (prefixseg, $000C)^); TerugkeerOffset := word (ptr (prefixseg, $000A)^); LangeNaam := '-----> Terminate Vector = ' + WordHex (TerugkeerSegment) + ':' + WordHex (TerugkeerOffset ) ; end else LangeNaam := ''; end {if ÆProgØ} else begin if Eigenaar = $0008 then begin if ActMCB^.Naam[1] = 'S' then case ActMCB^.Naam[2] of 'D' : Functie := 'SysD'; 'C' : Functie := 'SysP'; else Functie := 'Data'; end {case} else Functie := 'Data'; KorteNaam := ''; LangeNaam := ''; end {if Eigenaar = $0008} else begin if DitSegment + 1 = Omgeving then begin Functie := 'Env '; LangeNaam := Coda (Omgeving, Paragrafen); if EersteProg = Eigenaar then Meester := Omgeving; end {if ÆEnvØ} else begin move (ptr (DitSegment + 1, 0)^, Specificatie[1], 8); if (Specificatie = 'PATH=' + #0 + 'CO') or (Specificatie = 'COMSPEC=' ) or (Specificatie = 'OS=DRDOS' ) then begin Functie := 'Env' + chr (39); LangeNaam := Coda (DitSegment + 1, Paragrafen); if (EersteProg = Eigenaar) and (Meester = $0000 ) then Meester := DitSegment + 1; end else begin if Eigenaar = 0 then Functie := 'Free' else Functie := 'Data'; LangeNaam := ''; if (EersteProg = Eigenaar) and (Meester = $0000 ) then Meester := DitSegment + 1; end; end {else: not ÆEnvØ}; KorteNaam := ''; end {else: Eigenaar <> $0008}; end {else: not ÆProgØ}; {----- KorteNaam redigeren -----} for i := 1 to length (KorteNaam) do if KorteNaam[i] < #32 then KorteNaam[i] := '.'; KorteNaam := KorteNaam + ' '; {----- Oorsprong vaststellen -----} if EersteProg = Eigenaar then Oorsprong := '*' else Oorsprong := ' '; {----- Actueel proces (uitgaande Pijl) vaststellen -----} if Eigenaar = prefixseg then Pijl := '>' else Pijl := ' '; end {with Schakel^}; {----- MCB-opeenvolging onderzoeken / schakelverloop vaststellen -----} if (Zone = 'Upper') and (ActMCB^.Signatuur = 'Z') then begin Schakel^.Volgende := nil; EindeKeten := TRUE; end else begin ActMCB := ptr (seg (ActMCB^) + ActMCB^.Paragrafen + 1, 0); if ((ActMCB^.Signatuur <> 'M') and (ActMCB^.Signatuur <> 'Z')) or ($FFFF - ActMCB^.Paragrafen < seg (ActMCB^) ) then begin Schakel^.Volgende := nil; EindeKeten := TRUE; end else begin new (LaatsteSchakel); Schakel^.Volgende := LaatsteSchakel; LaatsteSchakel^.Vorige := Schakel; Schakel := LaatsteSchakel; end {else: (ÆMØ or ÆZØ) and Æteveel_ParagrafenØ}; end {else: ÆLowerØ or not ÆZØ}; until EindeKeten; {----- Terugtocht -----} while Schakel <> nil do with Schakel^ do begin {----- Ouder-proces vaststellen -----} TerugkeerSegment2 := TerugkeerSegment + (TerugkeerOffset div $10); if (DitSegment <= TerugkeerSegment2) and (DitSegment + Paragrafen >= TerugkeerSegment2) then OuderSegment := Eigenaar; {----- Meester-omgeving markeren -----} if DitSegment + 1 = Meester then Oorsprong := 'M'; {----- Schakel-verloop -----} Schakel := Schakel^.Vorige; end {while Schakel <> nil}; {----- Rapportage -----} writeln ('Chain of Memory Control Blocks in DOS version ', lo (dosversion), '.', ReleaseNummer, ':'); writeln; writeln ('MCB@ #Par Signat PSP@ Env@ Type !! Name File'); writeln ('---- ---- ------ ---- ---- ---- -- -------- ', '-----------------------------------'); Schakel := EersteSchakel; while Schakel <> nil do with Schakel^ do begin {----- Ouder-omgeving vaststellen -----} if Eigenaar = OuderSegment then begin if not Dos3punt2 then begin if (Functie = 'Env ') then begin Ouder := DitSegment + 1; Pijl := 'Û'; end else Pijl := '<'; end {if not Dos3punt2} else begin if ((Functie = 'Env' + chr (39)) or (Functie = 'Data')) and (Ouder = $0000) then begin Ouder := DitSegment + 1; Pijl := 'Û'; end else Pijl := '<'; end {else: Dos3punt2}; end {with Schakel^}; {----- Keten-weergave -----} writeln (WordHex (DitSegment) , ' ', WordHex (Paragrafen) , ' ', Signatuur , ' ', WordHex (Eigenaar) , ' ', WordHex (Omgeving) , ' ', Functie , ' ', Oorsprong, Pijl , ' ', KorteNaam , ' ', LangeNaam ); {----- Schakel-verloop -----} Schakel := Schakel^.Volgende; end {while Schakel <> nil}; {----- Afsluiting rapportage -----} writeln; write ('* = First command interpreter at '); if ProgGevonden then writeln (WordHex (EersteProg), ':0000') else writeln ('?'); write ('M = Master environment at '); if Meester > $0000 then writeln (WordHex (Meester), ':0000') else writeln ('?'); write ('< = Parent proces at '); writeln (WordHex (OuderSegment), ':0000'); write ('Û = Parent environment at '); if Ouder > $0000 then writeln (WordHex (Ouder), ':0000') else writeln ('?'); writeln ('> = Current proces at ', WordHex (prefixseg), ':0000'); writeln (' returns to ', WordHex (TerugkeerSegment), ':', WordHex (TerugkeerOffset)); END.
(위의 ASCII 127,이 프레젠테이션에 일부 ASCII / ANSI 번역 문제가있을 수 있습니다.)
-
==============================
4.레지스트리 방법은 모든 것을 영구적으로 수정하고 싶다면 setup.py에 있기 때문에 여기에서 원하는 것입니다.
레지스트리 방법은 모든 것을 영구적으로 수정하고 싶다면 setup.py에 있기 때문에 여기에서 원하는 것입니다.
일시적으로 프로세스 만 수행하면 os.environ이 트릭입니다.
-
==============================
5.os 모듈에는 getenv와 putenv 함수가있다. 그러나 putenv가 올바르게 작동하지 않고 Windows 레지스트리를 대신 사용해야하는 것으로 보입니다.
os 모듈에는 getenv와 putenv 함수가있다. 그러나 putenv가 올바르게 작동하지 않고 Windows 레지스트리를 대신 사용해야하는 것으로 보입니다.
이 토론 좀 봐.
-
==============================
6.이 Python 스크립트 [*]는 사용자의 레지스트리에 아무런 권한도 부여되지 않은 경우 레지스트리의 GLOBAL 환경 변수를 수정하려고 시도한 다음 모든 윈도우에 변경 사항을 알립니다.
이 Python 스크립트 [*]는 사용자의 레지스트리에 아무런 권한도 부여되지 않은 경우 레지스트리의 GLOBAL 환경 변수를 수정하려고 시도한 다음 모든 윈도우에 변경 사항을 알립니다.
""" 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 show_all(tree, path, key): i = 0 while True: try: n,v,t = winreg.EnumValue(key, i) print(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))) 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: show_all(tree_name, path, key) 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)) except FileNotFoundError as ex: print("!!!Cannot find %s due to: %s" % (reg_key(tree_name, path, varname), ex)) if __name__=='__main__': args = sys.argv argc = len(args) if argc > 3: print(__doc__.format(prog=args[0])) sys.exit() manage_registry_env_vars(*args[1:])
다음은 현재 경로의 어딘가에 setenv.py라는 파일에 저장되었다고 가정 할 때 몇 가지 사용 예제입니다. 이 예제에서는 관리자 권한이 없으므로 로컬 사용자의 레지스트리 트리에만 영향을줍니다.
> 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
[*] Adapted from : http://code.activestate.com/recipes/416087-persistent-environment-variables-on-windows/
from https://stackoverflow.com/questions/1085852/interface-for-modifying-windows-environment-variables-from-python by cc-by-sa and MIT license
'PYTHON' 카테고리의 다른 글
[PYTHON] XML 요소를 통해 반복하는 효율적인 방법 (0) | 2018.10.24 |
---|---|
[PYTHON] 파이썬을 이용한 이미지 컬러 검출 (0) | 2018.10.24 |
[PYTHON] Django 달 단위로 그룹화 주석 달기 (0) | 2018.10.24 |
[PYTHON] TensorFlow 모델 복원 (0) | 2018.10.24 |
[PYTHON] SimpleGUI를 Python 2.7 및 3.0 셸과 통합하는 방법 (0) | 2018.10.24 |