2

Я пытаюсь изменить системные пути на моем компьютере.

По какой-то причине, когда я открываю cmd через run, мои пути верны, как и ожидалось.

Однако, когда я нажимаю Shift+ правый клик в окне директории + открытого cmd, я получаю старый / другой путь, который даже не отображается в переменной Path ни в USER, ни в SYSTEM.

Пример:

CMD от RUN:

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]

CMD от Shift + правый клик:

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: вот пути

CMD от RUN:

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;

CMD от Shift + правый клик:

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;

2 ответа2

2

После того, как вы измените путь, вам нужно обязательно перезапустить Explorer, прежде чем пытаться снова открыть все свои терминалы. Таким образом, процесс Explorer принимает новый PATH и может передавать этот новый PATH новым программам, которые он выполняет.

1

Когда процесс запускается, по умолчанию переменные среды копируются из родительского процесса (который делает запрос на создание нового процесса) во вновь созданный процесс.

Когда вы используете метод Run , экземпляр explorer.exe обрабатывающий ваш рабочий стол, создаст экземпляр cmd , но когда вы используете метод Shift+ щелчок правой кнопкой мыши, другой экземпляр explorer , потомок svchost.exe (потомок services.exe , потомок wininit.exe) создаст экземпляр cmd .

Если обе версии проводника не имеют одинаковые блоки среды, экземпляры cmd не будут иметь одинаковые переменные.

Когда конфигурация переменных среды изменяется из системных свойств, ОС отправляет сообщение WM_SETTINGCHANGE всем верхним окнам. Экземпляр explorer обрабатывающий рабочий стол, получит его и обновит свой блок среды, но экземпляр, обрабатывающий просмотр файлов (тот, что находится под svchost.exe), не обрабатывает сообщение (нет, в данный момент я не знаю почему) и его блок среды не обновляется (все это было проверено с помощью ProcExp проверяющего среды процессов).

Как решить? Я не знаю. Возможно (нет, не проверено, у меня сейчас нет компилятора, просто идея) вместо того, чтобы использовать HWND_BROADCAST для отправки сообщения WM_SETTINGCHANGE , прямое сообщение процессу файлового браузера может решить эту проблему (или нет)

Как с этим бороться? Убейте экземпляр explorer , родительским процессом которого является svchost.exe . Когда запрашивается новый файловый браузер, запускается новый экземпляр с правильным блоком среды.

Для грубого подхода, просто чтобы попытаться запустить из командной строки

wmic process where "name='explorer.exe' and CommandLine like '%/factory%'" call Terminate

убить файловый браузер. Когда будет запрошен новый файловый браузер, будет создан новый процесс (теперь с обновленной средой), и новые экземпляры cmd увидят изменения.

отредактированный

После некоторых тестов с монитором API я увидел, что svchost.exe создает процесс explorer через вызов API CreateProcessAsUserW . В этом вызове аргумент lpEnvironment не является нулевым (если он нулевой, среда копируется из родительского в дочерний), поэтому svchost.exe создает среду для нового процесса. Но какой источник используется для создания новой среды?

Таким образом, я напрямую изменить переменную реестра regedit , чтобы гарантировать , что ни одно сообщение WM_SETTINGSCHANGE не отправляется, убитые экземпляр explorer файл браузера и создать два cmd экземпляров. Результат

  • Метод Run : экземпляр cmd не видит изменений. Поскольку родительского сообщения не было, его среда не изменилась, и новый запущенный процесс наследует неизмененную версию из explorer.exe который обрабатывает рабочий стол.

  • Shift+Click метод: изменения в реестре доступны.

Итак, svchost.exe извлекает информацию из реестра, чтобы создать блок среды для передачи во вновь созданный процесс.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .