¿Cuál es el significado del valor de cadena "NoWorkingDirectory" en el Registro de Windows?

¿Cuál es el significado del valor de cadena "NoWorkingDirectory" en el Registro de Windows?

El valor de cadena vacío "NoWorkingDirectory" se utiliza a menudo en el Registro de Windows cuando se crean elementos del menú contextual definidos por el usuario. Por ejemplo, para poder abrir PowerShell al hacer clic derecho en el fondo de la carpeta en el Explorador de Windows (en lugar de hacer clic derecho en la carpeta misma, en ese caso no se usa "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'"

Sin embargo, no tengo claro el propósito real de este valor. Siempre se usa vacío en todas las muestras que encontré. ¿Qué significa exactamente?

Respuesta1

WorkingDirectory es una propiedad de System.Diagnostics.ProcessStartInfo. Cuando hace clic derecho, está iniciando un nuevo proceso y esta configuración le permite iniciar un proceso sin que el directorio actual se convierta en el "Directorio de trabajo". Luego, el valor predeterminado es System32 para el comando que se ejecuta.

Por lo tanto, usaría "NoWorkingDirectory" cuando no desee que la ubicación en la que se hace clic con el botón derecho se convierta en parte de la ruta ambiental durante la duración del script. Configuración inútil en el 90% de los casos, a menos que tenga archivos con nombres similares en múltiples ubicaciones de ruta que podrían volverse difíciles a menos que se especifique "NoWorkingDirectory".

Ver más detalles aquí.

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

Respuesta2

Respuesta corta para usuarios de Windows sin conocimientos de programación

Ejecutar un ejecutable con uno (o más) nombre(s) de directorio/archivo pasados ​​como argumento(s) al ejecutable a través de un elemento del menú contextual del shell que se abre haciendo clic derecho en un directorio o archivo (en el lado derecho de unExplorador de archivos de Windowsventana) da como resultado que se inicie el ejecutable con el directorio de trabajo actual configurado para este ejecutable con

  1. el directorio que contiene el directorio/archivo en el que se hizo clic si no hay ningún valor de registro NoWorkingDirectorypresente
    o
  2. el directorio C:\Windows\System32o más precisamente %SystemRoot%\system32con el valor de registro NoWorkingDirectorypresente en el registro de Windows.

Muchos ejecutables y scripts que no están bien codificados requieren que la primera variante establezca el directorio de trabajo actual en el directorio que contiene el directorio o archivo a procesar. Ésa es la razón por la que la primera variante es la predeterminada.

En algunos casos, la primera variante provoca un comportamiento no deseado, como al ejecutar cmd.exepara procesar un script por lotes al que se le pasa el nombre del directorio/archivo en el que se hizo clic como argumento y se hace referencia al directorio/archivo utilizando suruta UNC.

La segunda variante NoWorkingDirectorypresente en el registro de Windows se puede utilizar para todos los ejecutables y scripts codificados realmente buenos.


Respuesta larga para usuarios y programadores de Windows interesados ​​en detalles

La biblioteca del kernel de Windows contiene la funciónProceso de creaciónque es utilizado por explorer.exey la mayoría de los otros ejecutables capaces de ejecutar otro ejecutable sin o con unINFORMACIÓN DE INICIOestructura para iniciar un ejecutable de Windows. Uno de los parámetros de la función CreateProcesses lpCurrentDirectory: un puntero largo a la cadena con la ruta del directorio para establecerlo como directorio de trabajo actual para el proceso a crear. El valor del puntero también puede ser nulo para indicar CreateProcessque se utilice el directorio actual del proceso que llama CreateProcesscomo directorio de trabajo actual para el proceso a crear. La mayoría de los ejecutables llaman CreateProcesscon un puntero nulo al parámetro de función lpCurrentDirectory.

ElExplorador de archivos de Windows( explorer.exe) llama CreateProcesscon la ruta del directorio que contiene el directorio/archivo en el que el usuario hizo clic con el botón secundario (generalmente el derecho) del dispositivo señalador (a menudo el mouse) y hizo clic en el menú contextual abierto en el elemento, lo que da como resultado iniciar un ejecutable con el elemento en el que se hizo clic. nombre del directorio/archivo como argumento.

El valor de la cadena de registro NoWorkingDirectorycambia el comportamiento de las explorer.exellamadas CreateProcessrelacionadas con el parámetro de función lpCurrentDirectory. El directorio actual es siempre el directorio del sistema de Windows con este valor de cadena de registro presente, es decir, el directorio %SystemRoot%\System32que en la mayoría de las máquinas con Windows se expande a C:\Windows\System32.

Eso se puede ver de la siguiente manera:

Por favor abre unsímbolo del sistemaventana y ejecute los siguientes comandos inofensivos:

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"

Las dos reglíneas de comando se agregan al registro de 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\""

El comando mdy las cuatro echolíneas de comando crean el archivo por lotes C:\Temp\DirTest\DirTest.cmdcon las siguientes líneas de comando:

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

Ahora empezarExplorador de archivos de Windowssi aún no se está ejecutando y busque el directorio en el lado izquierdo del árbol de carpetas C:\Windows\System32\drivers. Haga clic con el botón derecho del ratónen el lado derechoen la carpeta etcy haga clic izquierdo en el menú contextual abierto en el elementoSin prueba de directorio de trabajoAcabo de agregarlo antes al registro de Windows.

El archivo por lotes creado justo antes se ejecuta y se muestra en una ventana de consola:

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"

La primera línea de salida muestra el directorio actual establecido CreateProcesscomenzando cmd.execon los cuatro argumentos de acuerdo con la cadena pasada lpCurrentDirectorypor el proceso principal explorer.exe. Se puede observar que elExplorador de archivos de Windowsllamado CreateProcessen este caso con C:\Windows\System32\driversla ruta del directorio de trabajo actual.

La segunda línea de salida muestra con qué argumentos se inició el archivo por lotes, incluido el argumento 0, que es la cadena utilizada para hacer referencia al archivo por lotes agregado al registro de Windows.

La tercera línea muestra cómo cmd.exese inició explorer.exerespectivamente CreateProcess. cmd.exeaunque se almacena en el registro sin rodearlo, "está incluido "al iniciarlo explorer.exe.

El valor de la cadena de registro NoWorkingDirectoryno existe en este momento. Esa es la razón por la cual el directorio de trabajo actual cmd.exese establece en C:\Windows\System32\driverscuál es el directorio actual al explorer.exehacer clic derechoen el lado derechoen la carpeta etccon la carpeta actualmente activa enExplorador de archivos de Windowsser C:\Windows\System32\drivers.

Ahora haga clic derecho enExplorador de archivos de Windows en el lado izquierdoen el árbol de carpetas del directorio C:\Windowsmientras la carpeta actualmente activa está quieta C:\Windows\System32\driversy haga clic izquierdo en el menú contextual del elementoSin prueba de directorio de trabajo.

Hay una ventana de consola más abierta que muestra las siguientes líneas:

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"

La segunda y tercera línea son las esperadas. Pero el directorio actual no es ni C:\Windows\System32\driversni ni C:\tampoco C:\Windows. Por lo tanto, se puede ver que iniciar un ejecutable con el directorio que contiene un directorio no siempre funciona como se esperaba cuando el usuario hace clic derecho en el árbol de carpetas en el lado izquierdo de un directorio o una carpeta de shell virtual.

También se puede ver que la ruta del directorio de trabajo actual ni siquiera es la ruta real del directorio del sistema de Windows, como en este caso se mostraría C:\Windows\System32y no C:\WINDOWS\system32. Tenga en cuenta las diferencias en el caso de algunas letras. La ruta del directorio del sistema de Windows que realmente se utiliza aquí es una concatenación del valor del registro SystemRootbajo la clave HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersionque tiene el valor de la cadena C:\WINDOWSconcatenado con una cadena fija \system32. La ruta real del directorio es C:\Windows\System32.

Un archivo por lotes o ejecutable o cualquier otro script diseñado para ser ejecutado por explorer.exeprogramas o programas similares a través de un elemento del menú contextual siempre debe tener en cuenta que el directorio actual puede ser un directorio completamente diferente al directorio que contiene el directorio/nombre(s) de archivo pasados. . La llamada del proceso CreateProcessdefine qué directorio es el directorio actual para el proceso creado.

cmd.exetiene un comportamiento especial al iniciarse con la ruta del directorio actual como una ruta UNC. Cambia el directorio actual en este caso a %SystemRoot%(directorio de Windows) y genera la información:

\\ComputerName\SharedFolder\Resource
CMD.EXE se inició con la ruta anterior como directorio actual.
No se admiten rutas UNC. De forma predeterminada, el directorio de Windows.

Esto se hace por cmd.execompatibilidad con versiones anteriores debido a que muchos ejecutables no se ejecutan correctamente en la ruta del directorio actual y no comienzan con una letra de unidad y dos puntos.

Es posible ejecutar en una ventana del símbolo del sistema:

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

Eso deshabilita la verificación de la Convención de nomenclatura universal (UNC) para sesiones de comando y cmd.exetambién acepta un directorio actual con una ruta UNC.

Bien, volvamos al valor del registro NoWorkingDirectory. Ejecute en una ventana del símbolo del sistema ahora:

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

Se agrega el valor de la cadena de registro NoWorkingDirectorysin valor. Entonces el registro contiene ahora:

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

Tenga en cuenta que falta la tercera línea adicional en el resultado del registro publicado anteriormente.

EnExplorador de archivos de Windowsbotón derecho del ratónen el lado izquierdoen el directorio C:\Windowscon la carpeta actualmente activa quieta C:\Windows\System32\driversy haga clic izquierdo en el elemento del menú contextualSin prueba de directorio de trabajoexactamente como se hizo antes. La salida vuelve a ser como antes. Por tanto, no hay cambios para este caso de uso.

Haga clic derecho en siguienteen el lado derechoenExplorador de archivos de Windowsetcen el directorio C:\Windows\System32\driversy haga clic izquierdo en el elemento del menú contextualSin prueba de directorio de trabajo. Se abre una ventana de consola que muestra las siguientes líneas:

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"

La primera línea muestra la diferencia importante con el valor de la cadena de registro NoWorkingDirectorypresente, que ahora está C:\WINDOWS\system32en lugar de C:\Windows\system32\drivescomo antes. El directorio de trabajo actual ahora es siempre el directorio del sistema de Windows definido con %SystemRoot%\system32.

No importa si NoWorkingDirectoryse agrega al registro sin un valor de cadena o con un valor de cadena como C:\Windows. Incluso se puede agregar un valor de registro de tipo DWORDcon nombre NoWorkingDirectorycon valor 0o 1. El tipo de valor de registro NoWorkingDirectoryy su valor no importan para el shell de Windows ( explorer.exe). Solo importa si hay un valor de registro de nombre NoWorkingDirectorypresente o no en el registro de Windows bajo la clave que se utiliza para la extensión del shell.

La clave de registro agregada y el archivo por lotes se pueden usar para más análisis, como buscar un recurso de red usando una ruta UNC o hacer clic derecho en una carpeta de shell virtual en el lado izquierdo del árbol de carpetas. También se puede crear en C:\Temp\DirTestun directorio con nombre Development & Test(!) 100%y pasar el nombre de esta carpeta con la ruta completa a un archivo por lotes o ejecutable u otro script y ver qué sucede. Muchos archivos por lotes no logran procesar correctamente una cadena de argumento "C:\Temp\DirTest\Development & Test(!) 100%"debido a espacios, signos de exclamación, corchetes y un signo de porcentaje, aunque son un nombre de directorio válido que consta solo de caracteres ASCII.

La clave de registro y el archivo por lotes, así como el directorio creado utilizado para demostrar el comportamiento, deben eliminarse finalmente ejecutando los siguientes comandos en la ventana del símbolo del sistema después de cerrar todas las ventanas de la consola abiertas ejecutando DirTest.cmd:

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

Nota:Muchas de las propiedades de un archivo de acceso directo con extensión de archivo .lnkdefinen los valores pasados ​​porExploradora CreateProcesstravés de sus parámetros de función y la estructura STARTUPINFO. Por ejemplo la propiedadEmpezar endefine el valor de cadena al que lpCurrentDirectoryfinalmente apunta al utilizar el archivo de acceso directo para iniciar un ejecutable.

Una nota para programadores:

  • La C#clase de procesoes una clase contenedora de C# para CreateProcess.
  • la javaclase Constructor de procesosEn Windows hay una clase contenedora de Java para CreateProcess.
  • La pitónmódulo de subprocesoEn Windows hay un módulo contenedor de Python para CreateProcess.
  • El comando del procesador de comandos de Windows startadmite opciones que se pasan CreateProcessal cmd.exeusarlas, como la opción /Dque define la cadena que se pasa CreateProcessusando el parámetro de función lpCurrentDirectory.

Cada lenguaje de programación y scripting compatible con la ejecución de un ejecutable en Windows tiene una función o clase que llama a Windows CreateProcesscon o sin STARTUPINFOestructura.

Respuesta3

La propiedad del verbo "NoWorkingDirectory" no está documentada, por lo que esto es sólo una suposición:

Cmd.exe no admite recursos compartidos remotos (UNC) como directorio actual y si inicia Cmd.exe con dicho directorio de trabajo, imprimirá un mensaje de advertencia en la consola.

Si observa el registro "Abrir ventana de comando aquí", verá que inicia Cmd.exe con el pushdcomando y pushdadmite rutas UNC. NoWorkingDirectory sólo está ahí para evitar mostrar un mensaje de advertencia.

Realmente no es necesario para PowerShell.

información relacionada