我正在尝试更改我的计算机上的系统路径。
由于某种原因,当我通过运行打开 cmd 时,我的路径符合预期。
但是,当我在目录中按住 Shift 键并单击鼠标右键 + 打开 cmd 窗口时,我得到了一个旧的/不同的路径,该路径甚至没有显示在 USER 或 SYSTEM 的 Path 变量中。
例子:
来自 RUN 的 CMD:
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:以下是路径
来自 RUN 的 CMD:
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
处理桌面的实例将接收该消息并更新其环境块,但处理文件浏览的实例(位于 下的实例)不会处理该消息(不,目前我不知道为什么)并且其环境块不会更新(所有这些都已通过 sysinternal检查进程环境svchost.exe
进行了测试)。ProcExp
如何解决?我不知道。也许(没有测试过,我现在手头没有编译器,只是一个想法)而不是使用HWND_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在尝试再次打开所有终端之前。这样,Explorer 进程就会接受新的 PATH,并能够将该新 PATH 传输到它执行的新程序。