Что означает строковое значение «NoWorkingDirectory» в реестре Windows?

Что означает строковое значение «NoWorkingDirectory» в реестре Windows?

Пустое строковое значение "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".

Более подробную информацию смотрите здесь.

http://msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo.workingdirectory%28v=vs.110%29.aspx

решение2

Краткий ответ для пользователей Windows без навыков программирования

Запуск исполняемого файла с одним (или несколькими) именами каталогов/файлов, переданными в качестве аргументов исполняемому файлу через пункт контекстного меню оболочки, открываемый щелчком правой кнопкой мыши по каталогу или файлу (в правой частиПроводник Windowswindow) приводит к запуску исполняемого файла с текущим рабочим каталогом, установленным для этого исполняемого файла с

  1. каталог, содержащий выбранный каталог/файл, в реестре отсутствует NoWorkingDirectoryзначение
    или
  2. каталог C:\Windows\System32или, точнее, %SystemRoot%\system32значение реестра, NoWorkingDirectoryприсутствующее в реестре Windows.

Многие не очень хорошо закодированные исполняемые файлы и скрипты требуют первый вариант с текущим рабочим каталогом, установленным на каталог, содержащий каталог или файл для обработки. Вот почему первый вариант является вариантом по умолчанию.

В некоторых случаях первый вариант вызывает нежелательное поведение, например, при запуске cmd.exeпакетного скрипта, которому в качестве аргумента передается выбранное имя каталога/файла, а ссылка на каталог/файл осуществляется с использованием егоUNC-путь.

Второй вариант, NoWorkingDirectoryприсутствующий в реестре Windows, может использоваться для всех действительно хорошо закодированных исполняемых файлов и скриптов.


Подробный ответ для пользователей Windows и программистов, заинтересованных в подробностях

Библиотека ядра Windows содержит функциюСоздатьПроцесскоторый используется explorer.exeи большинство других исполняемых файлов, способных запускать другой исполняемый файл без или сSTARTUPINFOструктура для запуска исполняемого файла Windows. Один из параметров функции CreateProcesslpCurrentDirectoryдлинный указатель на строку с путем к каталогу, который устанавливается в качестве текущего рабочего каталога для создаваемого процесса. Значение указателя может быть также нулевым, чтобы указать на необходимость 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 это на самом деле не требуется.

Связанный контент