1. 程式人生 > >命令列使windows環境變數立即生效

命令列使windows環境變數立即生效

使用者變數和環境變數對於Windows系統級應用開發有著至關重要的意義。

最重要的一項功能便是我們可以通過DOS命令列或執行時指令進行本地過程呼叫,從而避免諸多路徑相關的問題,例如冗長的路徑字串造成的溢位,短路徑未設定,長路徑帶空格,路徑前後雙引號命令無效等。

對於大型整合系統而言,整合框架,整合指令碼等一系列第三方應用,也需要設定很多環境變數,這一點體現在它們的doc文件或readme中,這對於整合方案是不利好的,也對使用者體驗是不良好的。

在最近的一次系統級產品研發中,需要解決此項問題,即是一次安裝,自動設定。解決環境變數的設定,可以通過命令列,登錄檔來完成,但若要使其生效,需要登出或重新登入作業系統,這無疑是要解決的重要問題。

設定環境變數可以用以下幾種命令參考:

1.Reg登錄檔檔案

Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment]
"MyTestValue"="C:\Path\Dir"

這種辦法簡單可行,就是不能對已存在的值進行追加,例如追加Path環境變數

2.reg命令列

reg add "HKCU\Environment" /v MyTestValue /t reg_sz /d "C:\Path\Dir" /f

具體的可參照reg /?來進行檢視。
如果需要設定Path的追加值,則需要先查詢Path,在進行修改。
注意這裡不能用echo %path%來進行查詢,因為這裡的path是全部的搜尋路徑,即包括系統環境變數的,也包括使用者環境變數的。所以正確的做法應該還是查詢登錄檔。

:: 查詢登錄檔項值存入到mypath臨時變數中
for /f "delims=" %%i in (
'reg.exe query 
"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" 
/v "Path"'
) do set mypath="%%i" 
:: 對mypath進行擷取字串,去除前30個字元,去除後一個字元
set mypath=%mypath:~30,-1%
:: 對mypath追加路徑
set mypath=%mypath%;C:\Path\Dir
:: 重新設定並覆蓋到登錄檔中
reg add "
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /v Path /t REG_EXPAND_SZ /d "%mypath%" /f

3.wmi命令列

使用wmic命令查詢較為方便,但針對如下情況:

for /f "delims=" %%i in ('wmic.exe ENVIRONMENT where "name='Path' and username='<system>'" get VariableValue') do set mypath="%%i"

進行查詢賦值時,發現經過了三次賦值,最終賦值為””空而結束,在查閱了相關for迴圈指令後,都沒能解決,感情興趣的朋友可以試試,並分享下解決方法。執行後:
這裡寫圖片描述
出現這個問題後,就沒在忘後面寫了,其實剩下的內容很簡單

wmic ENVIRONMENT where "name='Path' and username='<system>'" set VariableValue="%mypath%;C:\Path\Dir"

4.立即生效設定的說明

有網友說如果是Win7以下系統,通過wmic設定後,是直接自動生效的,對於已載入的cmd或explorer當然是無法做到的。
win7以上系統wmic設定後,仍然無法立即生效,這裡查閱相關資料和其他網友的研究,可以通過setx進行設定

setx Path /K "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment\Path\" /M

這個命令執行後,在新開啟的cmd或explorer中,已更新的環境變數就已設定成功了。通常如果,需要在當前的cmd下也設定成功,可以補充SET Path = %mypath%即可。可針對已執行explorer或其他已開啟的程序,則無能為力。

5.傳送windows訊息進行更新廣播

SendMessageTimeout(HWND_BROADCAST,WM_SETTINGCHANGE,0,(LPARAM)TEXT(“Environment”),SMTO_ABORTIFHUNG,5000,&ret);

如果是Unicode編碼要注意轉碼TEXT或L,否則無效,多位元組的話強轉就可以了。但是經過測試發現,只有在新啟動的視窗中,新的環境變數被更新了,已執行的視窗仍然沒有被更新,雖然此函式設定了通知方式為廣播,但仍未生效,感興趣的朋友可以嘗試利用pid獲取視窗控制代碼進行再測試,這裡就不搞了。
經過以上各種方法嘗試,設定環境變數在整合系統專案中也是舉步維艱,存在bug的一步,整理了網上搜羅的資料和專案中嘗試的方法,也算是功德圓滿了。要搞它,這麼多方法,應該總有一個可以吧,再不行,咱們就彈框讓使用者不爽的重啟吧。

注意:
1.批處理和DOS命令,%%和%的區別。
2.C的字元編碼還是要小心以下,遵照規範,否則即便使用了也不會生效。