15

Empty "NoWorkingDirectory" string value is often used in Windows Registry when user-defined Right-Click menu items are created. For example to be able to open PowerShell when right-clicking on folder backround in Windows Explorer (as opposed to right-clicking on folder itself, in that case "NoWorkingDirectory" is not used):

[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'"

However, I am not clear on actual purpose of this value. It is always used empty in all samples I found. What exactly does it signify?

4
  • I would imagine if there was a directory value it would only work in that directory. Do you have other examples?
    – Ramhound
    Jan 17, 2014 at 20:48
  • windows7home.net/…
    – Joe Schmoe
    Jan 17, 2014 at 20:53
  • My guess is that it's the folder used to execute from if there's no Working Folder provided when the shell command is called (similar to the "Start In:" option in a Shortcut's properties). When empty it probably assumes the current folder. But again, this is just guessing. ;) Jan 17, 2014 at 21:47

3 Answers 3

12

WorkingDirectory is a property of the System.Diagnostics.ProcessStartInfo, when you Right Click, you are starting a new process and this setting allows you to start a process without the current directory becoming the "Working Directory". It then defaults to the System32 for the command being run.

So you would use "NoWorkingDirectory" when you are not wanting the location right clicked to become part of the environmental path for the duration of the script. Useless setting in 90% of cases, unless you have similar named files in multiple path locations which could get sticky unless "NoWorkingDirectory" is specified.

See more details here.

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

1
  • For instance, if I have a copy of DISM in a folder and right click on it, "NoWorkingDirectory" would allow me to access the copy in System32 over the one in the directory I right clicked on. See, it's kinda useless because more often than not I want the copy in the folder I clicked on. Jan 21, 2014 at 13:32
2

Short answer for Windows users without any programming skills

Running an executable with one (or more) directory/file name(s) passed as argument(s) to the executable via a shell context menu item opened by right clicking on a directory or file (on right side of a Windows File Explorer window) results in starting the executable with current working directory being set for this executable with

  1. the directory containing the clicked directory/file on no registry value NoWorkingDirectory present
    or
  2. the directory C:\Windows\System32 or more precisely %SystemRoot%\system32 with the registry value NoWorkingDirectory present in Windows registry.

Many not good coded executables and scripts require the first variant with current working directory being set to the directory containing the directory or file to process. That is the reason why the first variant is the default.

In some cases the first variant causes an unwanted behavior like on running cmd.exe to process a batch script which gets passed the clicked directory/file name as argument and the directory/file is referenced using its UNC path.

The second variant with NoWorkingDirectory present in the Windows registry can be used for all really good coded executables and scripts.


Long answer for Windows users and programmers interested in details

The Windows kernel library contains the function CreateProcess which is used by explorer.exe and most other executables capable running another executable without or with a STARTUPINFO structure to start a Windows executable. One of the parameters of function CreateProcess is lpCurrentDirectory – a long pointer to the string with directory path to set as current working directory for the process to create. The pointer value can be also null to instruct CreateProcess to use the current directory of the process calling CreateProcess as current working directory for the process to create. Most executables call CreateProcess with a null pointer for the function parameter lpCurrentDirectory.

The Windows File Explorer (explorer.exe) calls CreateProcess with the directory path of the directory containing the directory/file on which the user clicked with secondary (usually right) pointing device (often mouse) button and clicked in opened context menu on the item resulting in starting an executable with the clicked directory/file name as argument.

The registry string value NoWorkingDirectory changes the behavior on how explorer.exe calls CreateProcess regarding to function parameter lpCurrentDirectory. The current directory is always the system directory of Windows with this registry string value present, i.e. the directory %SystemRoot%\System32 which on most Windows machines expands to C:\Windows\System32.

That can be seen as follows:

Please open a command prompt window and run the following harmless commands:

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"

The two reg command lines add to Windows registry:

[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\""

The command md and the four echo command lines create the batch file C:\Temp\DirTest\DirTest.cmd with the following command lines:

@echo Batch file started with: %0 %*
@echo Current directory is: "%CD%"
@echo Command line used is: %CMDCMDLINE%
@pause

Now start Windows File Explorer on not already running and browse on left side in folder tree to the directory C:\Windows\System32\drivers. Click with the right mouse button on right side on the folder etc and left click in the opened context menu on the item No working directory test just added before to the Windows registry.

The just before created batch file is executed displaying in a console window:

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"

The first output line shows the current directory set by CreateProcess on starting cmd.exe with the four arguments according to the string passed with lpCurrentDirectory by the parent process explorer.exe. It can be seen that the Windows File Explorer called CreateProcess in this case with C:\Windows\System32\drivers as current working directory path.

The second output line shows with which arguments the batch file was started including argument 0 which is the string used to reference the batch file as added to Windows registry.

The third line outputs how cmd.exe itself was started by explorer.exe respectively CreateProcess. cmd.exe although stored in the registry without surrounding " is enclosed in " on being started by explorer.exe.

The registry string value NoWorkingDirectory does not exist at the moment. That is the reason why the current working directory for cmd.exe is set to C:\Windows\System32\drivers which is the current directory of explorer.exe on right clicking on right side on the folder etc with currently active folder in Windows File Explorer being C:\Windows\System32\drivers.

Now right click in Windows File Explorer on left side in folder tree on the directory C:\Windows while the currently active folder is still C:\Windows\System32\drivers and left click in context menu on the item No working directory test.

There is one more console window opened with displaying following lines:

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"

The second and the third line are as expected. But the current directory is neither C:\Windows\System32\drivers nor C:\ and also not C:\Windows. So it can be seen that starting an executable with the directory containing a directory does not always work as expected when the user right clicks in folder tree on left side on a directory or a virtual shell folder.

There can be also seen that the current working directory path is not even the real directory path of the Windows system directory as in this case would be displayed C:\Windows\System32 and not C:\WINDOWS\system32. Please note the differences in case of some letters. The Windows system directory path really used here is a concatenation of the registry value SystemRoot under key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion which has the string value C:\WINDOWS concatenated with fixed string \system32. The real directory path is C:\Windows\System32.

A batch file or executable or any other script designed for being executed by explorer.exe or similar programs via a context menu item should always take into account that the current directory can be a completely different directory than the directory containing the passed directory/file name(s). The process calling CreateProcess defines which directory is the current directory for the created process.

cmd.exe has a special behavior on being started with current directory path being a UNC path. It changes the current directory in this case to %SystemRoot% (Windows directory) and outputs the information:

\\ComputerName\SharedFolder\Resource
CMD.EXE was started with the above path as the current directory.
UNC paths are not supported. Defaulting to Windows directory.

That is done by cmd.exe for downwards compatibility because of many executables are not running correct on current directory path not starting with a drive letter and a colon.

It is possible to run in a command prompt window:

reg add "HKCU\Software\Microsoft\Command Processor" /v DisableUNCCheck /t REG_DWORD /d 1 /f

That disables the Universal Naming Convention (UNC) check for command sessions and cmd.exe accepts also a current directory with a UNC path.

Okay, back to registry value NoWorkingDirectory. Execute in a command prompt window now:

reg add "HKCU\Software\Classes\Directory\shell\NoWorkingDirectoryTest" /v NoWorkingDirectory /t REG_SZ

There is added the registry string value NoWorkingDirectory with no value. So the registry contains now:

[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\""

Please note the additional third line missing in registry output posted above.

In Windows File Explorer right click on left side on directory C:\Windows with currently active folder being still C:\Windows\System32\drivers and left click on context menu item No working directory test exactly as done before. The output is again as before. So there is no change for this use case.

Right click next on right side in Windows File Explorer on the directory etc in C:\Windows\System32\drivers and left click on context menu item No working directory test. A console window opens showing the following lines:

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"

The first line shows the important difference with the registry string value NoWorkingDirectory present which is now C:\WINDOWS\system32 instead of C:\Windows\system32\drives as before. The current working directory is now always the Windows system directory defined with %SystemRoot%\system32.

It does not matter if NoWorkingDirectory is added to registry without a string value or with a string value like C:\Windows. It can be even added a registry value of type DWORD with name NoWorkingDirectory with value 0 or 1. The registry value type of NoWorkingDirectory and its value does not matter for the Windows shell (explorer.exe). It only matters if there is a registry value of name NoWorkingDirectory present or not in Windows registry under the key being used for the shell extension.

The added registry key and the batch file can be used for more analyzes like browsing to a network resource using a UNC path or right clicking on a virtual shell folder on left side in the folder tree. There can be also created in C:\Temp\DirTest a directory with name Development & Test(!) 100% and pass this folder name with full path to a batch file or executable or other script and see what happens. Many batch files fail to process correct an argument string like "C:\Temp\DirTest\Development & Test(!) 100%" because of spaces and exclamation mark and round brackets and a percent sign although being a valid directory name consisting only of ASCII characters.

The registry key and the batch file as well as the created directory used to demonstrate the behavior should be deleted finally by executing the following commands in the command prompt window after closing all console windows opened by running DirTest.cmd:

reg delete "HKCU\Software\Classes\Directory\shell\NoWorkingDirectoryTest" /f
del C:\Temp\DirTest\DirTest.cmd
rd C:\Temp\DirTest
rd C:\Temp

Note: Many of the properties of a shortcut file with file extension .lnk define the values passed by Explorer to CreateProcess via its function parameters and the structure STARTUPINFO. For example the property Start in defines the string value to which lpCurrentDirectory finally points to on making use of the shortcut file to start an executable.

A note for programmers:

  • The C# Process class is a C# wrapper class for CreateProcess.
  • The Java class ProcessBuilder is on Windows a Java wrapper class for CreateProcess.
  • The Python subprocess module is on Windows a Python wrapper module for CreateProcess.
  • The Windows Command Processor command start supports options which are all passed to CreateProcess by cmd.exe on using them like the option /D which defines the string passed to CreateProcess using the function parameter lpCurrentDirectory.

Every programming and scripting language with support for running an executable on Windows has a function or class which calls on Windows CreateProcess without or with a STARTUPINFO structure.

1

The "NoWorkingDirectory" verb property is undocumented so this is just a guess:

Cmd.exe does not support remote shares (UNC) as the current directory and if you start Cmd.exe with such a working directory it will print a warning message to the console.

If you look at the "Open command window here" registration you will see that it starts Cmd.exe with the pushd command and pushd does support UNC paths. NoWorkingDirectory is just there to avoid displaying a warning message.

It is not really required for PowerShell.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .