
我正在嘗試更改計算機上的系統路徑。
由於某種原因,當我通過運行打開 cmd 時,我的路徑按預期正確。
但是,當我在目錄中 Shift+右鍵單擊 + 開啟 cmd 視窗時,我得到一個舊的/不同的路徑,該路徑甚至沒有顯示在 USER 或 SYSTEM 上的 Path 變數中。
例子:
運行命令:
C:\Users\PERSON>python
Python 2.7.7 (default, Jun 1 2014, 14:17:13) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
C:\Users\PERSON>pip
Usage:
pip <command> [options]
Shift + 右鍵點選 CMD:
C:\Users\PERSON>python
'python' is not recognized as an internal or external command,
operable program or batch file.
C:\Users\PERSON>pip
'pip' is not recognized as an internal or external command,
operable program or batch file.
我已經更改了系統和用戶中的路徑,以查看是否存在一些奇怪的問題,但問題仍然存在。
如果您需要更多信息,請告訴我。
編輯:我已經在路徑更改之間重新啟動了所有命令提示字元。
編輯2:這是路徑
運行命令:
C:\Users\PERSON>echo %path%
C:\ProgramData\Oracle\Java\javapath;
C:\Windows\system32;
C:\Windows;
C:\Windows\System32\Wbem;
C:\Windows\System32\WindowsPowerShell\v1.0\;
C:\EASE\Cygwin\Bin;
C:\bin;
C:\bin\Hardware;
C:\bin\OpenCV;
C:\bin\Qt;
C:\Program Files\Microsoft SQL Server\110\Tools\Binn\;
C:\Program Files (x86)\Microsoft Visual Studio\VC98\Bin;
C:\Program Files (x86)\Microsoft Visual Studio\Common\MSDev98\Bin;
C:\Python27\;
C:\Python27\Scripts;
C:\Program Files (x86)\Skype\Phone\;
C:\Program Files\SlikSvn\bin;
C:\Program Files (x86)\GNU Tools ARM Embedded\4.7 2012q4\bin;
Shift + 右鍵點選 CMD:
C:\Users\PERSON\Desktop>echo %path%
C:\ProgramData\Oracle\Java\javapath;
C:\Windows\system32;
C:\Windows;
C:\Windows\System32\Wbem;
C:\Windows\System32\WindowsPowerShell\v1.0\;
C:\bin;
C:\bin\Hardware;
C:\bin\OpenCV;
C:\bin\Qt;
C:\Program Files\Microsoft SQL Server\110\Tools\Binn\;
C:\Program Files (x86)\Microsoft Visual Studio\VC98\Bin;
C:\Program Files (x86)\Microsoft Visual Studio\Common\MSDev98\Bin;
C:\Program Files (x86)\Skype\Phone\;
C:\Program Files (x86)\GNU ToolsARM Embedded\4.7 2012q4\bin;
答案1
當一個進程啟動時,預設情況下環境變數是複製的從父進程(發出建立新進程的請求)到新建立的進程。
當您使用Run
方法時,explorer.exe
處理桌面的實例將建立該cmd
實例,但當您使用Shift+右鍵單擊方法時,另一個explorer
實例svchost.exe
(子級services.exe
,子級wininit.exe
)將建立該cmd
實例。
如果兩個資源管理器版本沒有相同的環境區塊,則cmd
實例將不會具有相同的變數。
當環境變數的配置從系統屬性變更時,作業系統將向WM_SETTINGCHANGE
所有頂級視窗發送訊息。處理桌面的實例explorer
將接收該訊息並更新其環境塊,但處理文件瀏覽的實例(下圖所示svchost.exe
)不會處理該訊息(不,目前我不知道為什麼)並且其環境塊也不會處理該訊息。ProcExp
怎麼解決?我不知道。也許(不,未經測試,我現在手邊沒有編譯器,只是一個想法)而不是使用 aHWND_BROADCAST
來發送WM_SETTINGCHANGE
訊息,直接向文件瀏覽器進程發送訊息可以解決它(或不能)
怎麼處理呢?殺死explorer
父進程為 的實例svchost.exe
。當請求新的文件瀏覽器時,將使用正確的環境區塊啟動新實例。
對於粗略的方法,只是嘗試從命令列運行
wmic process where "name='explorer.exe' and CommandLine like '%/factory%'" call Terminate
殺死文件瀏覽器。當請求新的文件瀏覽器時,將建立一個新進程(現在環境已更新)並且新cmd
實例將看到變更。
已編輯
在使用 api 監視器進行一些測試後,我發現它是透過api 呼叫svchost.exe
創建進程的。在此呼叫中,參數不為空(如果為空,則環境從父進程複製到子進程),為新進程建立環境也是如此。但是,使用什麼來源來創造新環境呢?explorer
CreateProcessAsUserW
lpEnvironment
svchost.exe
因此,我直接更改註冊表中的變數(regedit
)以確保沒有WM_SETTINGSCHANGE
訊息發送,殺死文件瀏覽器explorer
實例並創建兩個cmd
實例。結果是
Run
方法:cmd
實例看不到變化。由於沒有任何訊息發送給父進程,因此其環境沒有更改,並且新啟動的進程從explorer.exe
處理桌面的進程繼承了未更改的版本。Shift+點選方法:登錄中的變更可用。
因此,svchost.exe
正在從註冊表中檢索資訊以建立一個環境區塊以傳遞給新建立的進程。
答案2
更改路徑後,您需要確保重新啟動資源管理器在嘗試再次打開所有終端之前。這樣,Explorer 程序就會接收新的 PATH,並且能夠將該新的 PATH 傳送到它執行的新程式。