最近寫在一個(gè) windows 上快速切換 python 環(huán)境的軟件(PySwitch)的時(shí)候遇到一個(gè)問題谴轮。就是用戶下載后臺(tái),需要用戶手動(dòng)為軟件添加環(huán)境變量破喻,以便在任何地方都可以調(diào)起軟件职祷。后來一想,手動(dòng)添加環(huán)境變量太麻煩了蚁鳖,為什么不在安裝軟件初始化的時(shí)候自動(dòng)去添加環(huán)境變量呢磺芭。想到就動(dòng)手...
于是就百度了一圈,查到可以通過 os.environ
中的 os.environ.setdefault
方法可以修改系統(tǒng)環(huán)境變量醉箕。經(jīng)過實(shí)驗(yàn)使用后發(fā)現(xiàn)钾腺,os.environ
只能影響到當(dāng)前運(yùn)行程序,無法保存到系統(tǒng)中讥裤。無耐只好放棄...
本著不拋棄不放棄的理念放棒,想到 windos 是可以通過 dos 命令
來改變環(huán)境變量的,所以想到了一個(gè)曲線救國(guó)的方法己英,通過 python 來運(yùn)行 dos 命令來修改系統(tǒng)環(huán)境變量间螟。通過查找資料,發(fā)現(xiàn)可以通過 setx
和 reg add(修改注冊(cè)表)
兩命令來修改系統(tǒng)環(huán)境變量损肛。
STEX 和 REG ADD 的優(yōu)劣
- stex :
stex
命令功能強(qiáng)大厢破,使用較為簡(jiǎn)單,但setx
有截?cái)?1024 字符設(shè)置荧关,所以超過 1024 字符無法使用stex
命令 - reg add :沒有字符截?cái)喔绒龋褂蒙陷^
setx
繁瑣
setx 設(shè)置環(huán)境變量
# 用戶環(huán)境變量
setx key value
# 系統(tǒng)環(huán)境變量
setx /M key value
reg add 設(shè)置環(huán)境變量
# 用戶環(huán)境變量注冊(cè)表位置
set regPath= HKEY_CURRENT_USER\Environment
# 系統(tǒng)環(huán)境變量注冊(cè)表位置
set regPath= HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session" "Manager\Environment
reg add %regPath% /v %key% /t REG_EXPAND_SZ /d "%oldValue%;%value%" /f
在 Python 中使用
SET_ENV=r'''
@echo
set %{key}%={value}
echo %{key}%
if {user}==sys (
setx /M{key} "%{key}%"
) else (
setx {key} "%{key}%"
)
'''
ADD_ENV=r'''
@echo off
if {user}==sys (
set regPath= HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session" "Manager\Environment
) else (
set regPath= HKEY_CURRENT_USER\Environment
)
set key={key}
set value={value}
:: 判斷是否存在該路徑
reg query %regPath% /v %key% 1>nul 2>nul
if %ERRORLEVEL%==0 (
:: 取值
For /f "tokens=3* delims= " %%i in ('Reg Query %regPath% /v %key% ') do (
if "%%j"=="" (Set oldValue=%%i) else (Set oldValue=%%i %%j)
)
) else Set oldValue="."
:: 備份注冊(cè)表
reg export %regPath% %~dp0%~n0.reg
:: 寫入環(huán)境變量
if "%oldValue%"=="." (
reg add %regPath% /v %key% /t REG_EXPAND_SZ /d "%value%" /f
) else (
reg add %regPath% /v %key% /t REG_EXPAND_SZ /d "%oldValue%;%value%" /f
)
'''
# 連續(xù)運(yùn)行 bat 命令
def runbat(self, bat):
tmp_bat_file = 'tmp.bat'
with open(tmp_bat_file, 'w') as f:
f.writelines(bat)
self.runcmd(tmp_bat_file)
# 添加環(huán)境變量
def _append_env(self, is_sys, key, value):
# 運(yùn)行設(shè)置環(huán)境變量命令
user = 'sys' if is_sys else 'me'
cmds = ADD_ENV.format(user=user, key=key, value=value)
self.runbat(cmds)
# 設(shè)置環(huán)境變量
def _set_env(self, is_sys, key, value):
user = 'sys' if is_sys else 'me'
cmds = SET_ENV.format(user=user, key=key, value=value)
self.runbat(cmds)