
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í.
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
- el directorio que contiene el directorio/archivo en el que se hizo clic si no hay ningún valor de registro
NoWorkingDirectory
presente
o - el directorio
C:\Windows\System32
o más precisamente%SystemRoot%\system32
con el valor de registroNoWorkingDirectory
presente 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.exe
para 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 NoWorkingDirectory
presente 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.exe
y 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 CreateProcess
es 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 CreateProcess
que se utilice el directorio actual del proceso que llama CreateProcess
como directorio de trabajo actual para el proceso a crear. La mayoría de los ejecutables llaman CreateProcess
con un puntero nulo al parámetro de función lpCurrentDirectory
.
ElExplorador de archivos de Windows( explorer.exe
) llama CreateProcess
con 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 NoWorkingDirectory
cambia el comportamiento de las explorer.exe
llamadas CreateProcess
relacionadas 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%\System32
que 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 reg
lí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 md
y las cuatro echo
líneas de comando crean el archivo por lotes C:\Temp\DirTest\DirTest.cmd
con 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 etc
y 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 CreateProcess
comenzando cmd.exe
con los cuatro argumentos de acuerdo con la cadena pasada lpCurrentDirectory
por el proceso principal explorer.exe
. Se puede observar que elExplorador de archivos de Windowsllamado CreateProcess
en este caso con C:\Windows\System32\drivers
la 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.exe
se inició explorer.exe
respectivamente CreateProcess
. cmd.exe
aunque se almacena en el registro sin rodearlo, "
está incluido "
al iniciarlo explorer.exe
.
El valor de la cadena de registro NoWorkingDirectory
no existe en este momento. Esa es la razón por la cual el directorio de trabajo actual cmd.exe
se establece en C:\Windows\System32\drivers
cuál es el directorio actual al explorer.exe
hacer clic derechoen el lado derechoen la carpeta etc
con 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:\Windows
mientras la carpeta actualmente activa está quieta C:\Windows\System32\drivers
y 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\drivers
ni 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\System32
y 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 SystemRoot
bajo la clave HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion
que tiene el valor de la cadena C:\WINDOWS
concatenado 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.exe
programas 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 CreateProcess
define qué directorio es el directorio actual para el proceso creado.
cmd.exe
tiene 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.exe
compatibilidad 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.exe
tambié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 NoWorkingDirectory
sin 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:\Windows
con la carpeta actualmente activa quieta C:\Windows\System32\drivers
y 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 Windowsetc
en el directorio C:\Windows\System32\drivers
y 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 NoWorkingDirectory
presente, que ahora está C:\WINDOWS\system32
en lugar de C:\Windows\system32\drives
como antes. El directorio de trabajo actual ahora es siempre el directorio del sistema de Windows definido con %SystemRoot%\system32
.
No importa si NoWorkingDirectory
se 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 DWORD
con nombre NoWorkingDirectory
con valor 0
o 1
. El tipo de valor de registro NoWorkingDirectory
y su valor no importan para el shell de Windows ( explorer.exe
). Solo importa si hay un valor de registro de nombre NoWorkingDirectory
presente 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\DirTest
un 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 .lnk
definen los valores pasados porExploradora CreateProcess
través de sus parámetros de función y la estructura STARTUPINFO
. Por ejemplo la propiedadEmpezar endefine el valor de cadena al que lpCurrentDirectory
finalmente 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
start
admite opciones que se pasanCreateProcess
alcmd.exe
usarlas, como la opción/D
que define la cadena que se pasaCreateProcess
usando el parámetro de funciónlpCurrentDirectory
.
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 CreateProcess
con o sin STARTUPINFO
estructura.
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 pushd
comando y pushd
admite rutas UNC. NoWorkingDirectory sólo está ahí para evitar mostrar un mensaje de advertencia.
Realmente no es necesario para PowerShell.