
Пустое строковое значение "NoWorkingDirectory" часто используется в реестре Windows при создании пользовательских элементов меню правой кнопки мыши. Например, чтобы иметь возможность открывать PowerShell при щелчке правой кнопкой мыши на фоне папки в проводнике Windows (в отличие от щелчка правой кнопкой мыши на самой папке, в этом случае "NoWorkingDirectory" не используется):
[HKEY_CLASSES_ROOT\Directory\Background\shell\powershell]
@="Open PowerShell Here"
"NoWorkingDirectory"=""
[HKEY_CLASSES_ROOT\Directory\Background\shell\powershell\command]
@="C:\\\\Windows\\\\System32\\\\WindowsPowerShell\\\\v1.0\\\\powershell.exe -NoExit -Command Set-Location -LiteralPath '%V'"
Однако мне не ясна истинная цель этого значения. Оно всегда используется пустым во всех найденных мной образцах. Что именно оно означает?
решение1
WorkingDirectory — это свойство System.Diagnostics.ProcessStartInfo, при щелчке правой кнопкой мыши вы запускаете новый процесс, и эта настройка позволяет вам запускать процесс без того, чтобы текущий каталог стал «Рабочим каталогом». Затем по умолчанию для выполняемой команды используется System32.
Таким образом, вы бы использовали "NoWorkingDirectory", когда не хотите, чтобы место, по которому нажата правая кнопка мыши, стало частью пути окружения на время выполнения скрипта. Бесполезная настройка в 90% случаев, если только у вас нет файлов с похожими именами в нескольких местах пути, которые могут стать липкими, если не указано "NoWorkingDirectory".
Более подробную информацию смотрите здесь.
решение2
Краткий ответ для пользователей Windows без навыков программирования
Запуск исполняемого файла с одним (или несколькими) именами каталогов/файлов, переданными в качестве аргументов исполняемому файлу через пункт контекстного меню оболочки, открываемый щелчком правой кнопкой мыши по каталогу или файлу (в правой частиПроводник Windowswindow) приводит к запуску исполняемого файла с текущим рабочим каталогом, установленным для этого исполняемого файла с
- каталог, содержащий выбранный каталог/файл, в реестре отсутствует
NoWorkingDirectory
значение
или - каталог
C:\Windows\System32
или, точнее,%SystemRoot%\system32
значение реестра,NoWorkingDirectory
присутствующее в реестре Windows.
Многие не очень хорошо закодированные исполняемые файлы и скрипты требуют первый вариант с текущим рабочим каталогом, установленным на каталог, содержащий каталог или файл для обработки. Вот почему первый вариант является вариантом по умолчанию.
В некоторых случаях первый вариант вызывает нежелательное поведение, например, при запуске cmd.exe
пакетного скрипта, которому в качестве аргумента передается выбранное имя каталога/файла, а ссылка на каталог/файл осуществляется с использованием егоUNC-путь.
Второй вариант, NoWorkingDirectory
присутствующий в реестре Windows, может использоваться для всех действительно хорошо закодированных исполняемых файлов и скриптов.
Подробный ответ для пользователей Windows и программистов, заинтересованных в подробностях
Библиотека ядра Windows содержит функциюСоздатьПроцесскоторый используется explorer.exe
и большинство других исполняемых файлов, способных запускать другой исполняемый файл без или сSTARTUPINFOструктура для запуска исполняемого файла Windows. Один из параметров функции CreateProcess
– lpCurrentDirectory
длинный указатель на строку с путем к каталогу, который устанавливается в качестве текущего рабочего каталога для создаваемого процесса. Значение указателя может быть также нулевым, чтобы указать на необходимость CreateProcess
использования текущего каталога вызывающего процесса CreateProcess
в качестве текущего рабочего каталога для создаваемого процесса. Большинство исполняемых файлов вызываются CreateProcess
с нулевым указателем для параметра функции lpCurrentDirectory
.
TheПроводник Windows( explorer.exe
) вызывается CreateProcess
с путем к каталогу, содержащему каталог/файл, по которому пользователь щелкнул вторичной (обычно правой) кнопкой указывающего устройства (часто мышью) и щелкнул в открытом контекстном меню по элементу, что приводит к запуску исполняемого файла с именем выбранного каталога/файла в качестве аргумента.
Значение строки реестра NoWorkingDirectory
изменяет поведение того, как explorer.exe
вызовы CreateProcess
относятся к параметру функции lpCurrentDirectory
. Текущим каталогом всегда является системный каталог Windows с этим значением строки реестра, т. е. каталог, %SystemRoot%\System32
который на большинстве машин Windows расширяется до C:\Windows\System32
.
Это можно увидеть следующим образом:
Пожалуйста, откройтекомандная строкаокно и выполните следующие безвредные команды:
reg add "HKCU\Software\Classes\Directory\shell\NoWorkingDirectoryTest" /ve /d "No working directory test"
reg add "HKCU\Software\Classes\Directory\shell\NoWorkingDirectoryTest\command" /ve /d "cmd.exe /D /C C:\Temp\DirTest\DirTest.cmd \"%V"\""
md "C:\Temp\DirTest"
echo @echo Current directory is: ^"%^CD%^">"C:\Temp\DirTest\DirTest.cmd"
echo @echo Batch file started with: %0 %*>>"C:\Temp\DirTest\DirTest.cmd"
echo @echo Command line used is: %^CMDCMDLINE%>>"C:\Temp\DirTest\DirTest.cmd"
echo @pause>>"C:\Temp\DirTest\DirTest.cmd"
Две reg
командные строки добавляют в реестр Windows:
[HKEY_CURRENT_USER\Software\Classes\Directory\shell\NoWorkingDirectoryTest]
@="No working directory test"
[HKEY_CURRENT_USER\Software\Classes\Directory\shell\NoWorkingDirectoryTest\command]
@="cmd.exe /D /C \"C:\\Temp\\DirTest\\DirTest.cmd\" \"%V\""
Команда md
и четыре echo
командные строки создают пакетный файл C:\Temp\DirTest\DirTest.cmd
со следующими командными строками:
@echo Batch file started with: %0 %*
@echo Current directory is: "%CD%"
@echo Command line used is: %CMDCMDLINE%
@pause
Теперь начинайПроводник Windowsна еще не запущенном и просмотрите слева в дереве папок каталог C:\Windows\System32\drivers
. Щелкните правой кнопкой мышина правой сторонена папке etc
и щелкните левой кнопкой мыши в открывшемся контекстном меню на элементеНет рабочего теста каталогатолько что добавлен в реестр Windows.
Только что созданный пакетный файл запускается и отображается в окне консоли:
Current directory is: "C:\Windows\System32\drivers"
Batch file started with: C:\Temp\DirTest\DirTest.cmd "C:\Windows\System32\drivers\etc"
Command line used is: "cmd.exe" /D /C C:\Temp\DirTest\DirTest.cmd "C:\Windows\System32\drivers\etc"
Первая строка вывода показывает текущий каталог, установленный CreateProcess
при запуске cmd.exe
с четырьмя аргументами в соответствии со строкой, переданной lpCurrentDirectory
родительским процессом explorer.exe
. Видно, чтоПроводник WindowsCreateProcess
в этом случае вызывается с C:\Windows\System32\drivers
указанием текущего пути к рабочему каталогу.
Вторая строка вывода показывает, с какими аргументами был запущен пакетный файл, включая аргумент 0, который представляет собой строку, используемую для ссылки на пакетный файл, добавленный в реестр Windows.
Третья строка выводит, как cmd.exe
она сама была запущена explorer.exe
соответственно CreateProcess
. cmd.exe
хотя она хранится в реестре без окружения, "
заключена в "
при запуске explorer.exe
.
Значение строки реестра NoWorkingDirectory
в данный момент не существует. Вот почему текущий рабочий каталог для cmd.exe
устанавливается на C:\Windows\System32\drivers
который является текущим каталогом при explorer.exe
щелчке правой кнопкой мышина правой сторонена папке etc
с текущей активной папкой вПроводник Windowsсуществование C:\Windows\System32\drivers
.
Теперь щелкните правой кнопкой мышиПроводник Windows на левой сторонев дереве папок каталога, C:\Windows
пока текущая активная папка неподвижна C:\Windows\System32\drivers
, и щелкните левой кнопкой мыши в контекстном меню на элементеНет рабочего теста каталога.
Откроется еще одно консольное окно, в котором будут отображаться следующие строки:
Current directory is: "C:\WINDOWS\system32"
Batch file started with: C:\Temp\DirTest\DirTest.cmd "C:\Windows"
Command line used is: "cmd.exe" /D /C C:\Temp\DirTest\DirTest.cmd "C:\Windows"
Вторая и третья строки соответствуют ожидаемым. Но текущий каталог — ни , C:\Windows\System32\drivers
ни C:\
, а также не C:\Windows
. Таким образом, можно заметить, что запуск исполняемого файла с каталогом, содержащим каталог, не всегда работает так, как ожидается, когда пользователь щелкает правой кнопкой мыши в дереве папок слева на каталоге или папке виртуальной оболочки.
Также можно увидеть, что текущий рабочий путь к каталогу даже не является реальным путем к системному каталогу Windows, как в этом случае отображалось бы, C:\Windows\System32
а не C:\WINDOWS\system32
. Обратите внимание на различия в регистре некоторых букв. Путь к системному каталогу Windows, который действительно используется здесь, представляет собой объединение значения реестра SystemRoot
в разделе HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion
, который имеет строковое значение, C:\WINDOWS
объединенное с фиксированной строкой \system32
. Реальный путь к каталогу — C:\Windows\System32
.
Пакетный файл или исполняемый файл или любой другой скрипт, предназначенный для выполнения explorer.exe
или похожими программами через пункт контекстного меню, всегда должен учитывать, что текущий каталог может быть совершенно другим каталогом, нежели каталог, содержащий переданные имена каталогов/файлов. Вызов процесса CreateProcess
определяет, какой каталог является текущим каталогом для созданного процесса.
cmd.exe
имеет особое поведение при запуске с текущим путем к каталогу, являющимся путем UNC. Он изменяет текущий каталог в этом случае на %SystemRoot%
(каталог Windows) и выводит информацию:
\\ComputerName\SharedFolder\Resource
CMD.EXE был запущен с указанным выше путем в качестве текущего каталога.
Пути UNC не поддерживаются. По умолчанию используется каталог Windows.
Это сделано cmd.exe
для обеспечения обратной совместимости, поскольку многие исполняемые файлы некорректно запускаются в текущем каталоге, путь к которому не начинается с буквы диска и двоеточия.
Можно запустить в окне командной строки:
reg add "HKCU\Software\Microsoft\Command Processor" /v DisableUNCCheck /t REG_DWORD /d 1 /f
Это отключает проверку универсального соглашения об именовании (UNC) для сеансов команд и cmd.exe
также принимает текущий каталог с путем UNC.
Хорошо, вернемся к значению реестра NoWorkingDirectory
. Выполните в окне командной строки:
reg add "HKCU\Software\Classes\Directory\shell\NoWorkingDirectoryTest" /v NoWorkingDirectory /t REG_SZ
Добавлено значение строки реестра NoWorkingDirectory
без значения. Таким образом, реестр теперь содержит:
[HKEY_CURRENT_USER\Software\Classes\Directory\shell\NoWorkingDirectoryTest]
@="No working directory test"
"NoWorkingDirectory"=""
[HKEY_CURRENT_USER\Software\Classes\Directory\shell\NoWorkingDirectoryTest\command]
@="cmd.exe /D /C C:\\Temp\\DirTest\\DirTest.cmd \"%V\""
Обратите внимание на отсутствие третьей строки в выходных данных реестра, размещенных выше.
ВПроводник Windowsщелкните правой кнопкой мышина левой сторонев каталоге C:\Windows
с активной в данный момент папкой, которая неподвижна, C:\Windows\System32\drivers
и щелкните левой кнопкой мыши по пункту контекстного менюНет рабочего теста каталогаточно так же, как и раньше. Вывод снова такой же, как и раньше. Так что для этого варианта использования нет никаких изменений.
Щелкните правой кнопкой мыши и выберите «Далее».на правой стороневПроводник Windowsetc
в каталоге C:\Windows\System32\drivers
и щелкните левой кнопкой мыши по пункту контекстного менюНет рабочего теста каталога. Откроется окно консоли, в котором будут показаны следующие строки:
Current directory is: "C:\WINDOWS\system32"
Batch file started with: C:\Temp\DirTest\DirTest.cmd "C:\Windows\System32\drivers\etc"
Command line used is: "cmd.exe" /D /C C:\Temp\DirTest\DirTest.cmd "C:\Windows\System32\drivers\etc"
Первая строка показывает важное различие с NoWorkingDirectory
присутствующим значением строки реестра, которое теперь C:\WINDOWS\system32
вместо C:\Windows\system32\drives
того, как раньше. Текущим рабочим каталогом теперь всегда является системный каталог Windows, определенный с помощью %SystemRoot%\system32
.
Не имеет значения, NoWorkingDirectory
добавляется ли в реестр без строкового значения или со строковым значением, например C:\Windows
. Можно даже добавить значение реестра типа DWORD
с именем NoWorkingDirectory
со значением 0
или 1
. Тип значения реестра NoWorkingDirectory
и его значение не имеют значения для оболочки Windows ( explorer.exe
). Имеет значение только то, присутствует ли значение реестра с именем NoWorkingDirectory
в реестре Windows в разделе, используемом для расширения оболочки.
Добавленный раздел реестра и пакетный файл можно использовать для дополнительных анализов, таких как просмотр сетевого ресурса с использованием пути UNC или щелчок правой кнопкой мыши по папке виртуальной оболочки слева в дереве папок. Также можно создать каталог C:\Temp\DirTest
с именем Development & Test(!) 100%
и передать это имя папки с полным путем пакетному файлу или исполняемому файлу или другому скрипту и посмотреть, что произойдет. Многие пакетные файлы не могут правильно обработать строку аргумента, например, "C:\Temp\DirTest\Development & Test(!) 100%"
из-за пробелов, восклицательного знака, круглых скобок и знака процента, хотя это допустимое имя каталога, состоящее только из символов ASCII.
Раздел реестра и пакетный файл, а также созданный каталог, используемый для демонстрации поведения, следует окончательно удалить, выполнив следующие команды в окне командной строки после закрытия всех окон консоли, открытых с помощью запуска DirTest.cmd
:
reg delete "HKCU\Software\Classes\Directory\shell\NoWorkingDirectoryTest" /f
del C:\Temp\DirTest\DirTest.cmd
rd C:\Temp\DirTest
rd C:\Temp
Примечание:Многие свойства файла ярлыка с расширением файла .lnk
определяют передаваемые им значения.Исследовательчерез CreateProcess
его функциональные параметры и структуру STARTUPINFO
. Например, свойствоНачинатьопределяет строковое значение, на которое lpCurrentDirectory
в конечном итоге указывает при использовании файла ярлыка для запуска исполняемого файла.
Примечание для программистов:
- С#Класс процесса— это класс-оболочка C# для
CreateProcess
. - Явакласс ProcessBuilderявляется в Windows классом-оболочкой Java для
CreateProcess
. - Питонмодуль подпроцессав Windows есть модуль-обертка Python для
CreateProcess
. - Команда процессора команд Windows
start
поддерживает параметры, которые передаютсяCreateProcess
приcmd.exe
их использовании, например параметр/D
, определяющий строку, передаваемуюCreateProcess
с помощью параметра функцииlpCurrentDirectory
.
Каждый язык программирования и сценариев, поддерживающий запуск исполняемого файла в Windows, имеет функцию или класс, который вызывается в Windows CreateProcess
без структуры или со STARTUPINFO
структурой.
решение3
Свойство глагола «NoWorkingDirectory» недокументировано, поэтому это всего лишь предположение:
Cmd.exe не поддерживает удаленные общие ресурсы (UNC) в качестве текущего каталога, и если вы запустите Cmd.exe с таким рабочим каталогом, он выведет предупреждающее сообщение на консоль.
Если вы посмотрите на регистрацию "Открыть командное окно здесь", вы увидите, что она запускает Cmd.exe с pushd
командой и pushd
поддерживает пути UNC. NoWorkingDirectory присутствует только для того, чтобы избежать отображения предупреждающего сообщения.
Для PowerShell это на самом деле не требуется.