
O valor da string "NoWorkingDirectory" vazia é frequentemente usado no Registro do Windows quando itens de menu do botão direito definidos pelo usuário são criados. Por exemplo, para poder abrir o PowerShell ao clicar com o botão direito do mouse na pasta no Windows Explorer (em vez de clicar com o botão direito na própria pasta, nesse caso "NoWorkingDirectory" não é usado):
[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'"
No entanto, não estou claro sobre o propósito real desse valor. É sempre usado vazio em todas as amostras que encontrei. O que exatamente isso significa?
Responder1
WorkingDirectory é uma propriedade de System.Diagnostics.ProcessStartInfo, quando você clica com o botão direito, você está iniciando um novo processo e esta configuração permite iniciar um processo sem que o diretório atual se torne o "Diretório de Trabalho". Em seguida, o padrão é System32 para o comando que está sendo executado.
Portanto, você usaria "NoWorkingDirectory" quando não quiser que o local clicado com o botão direito se torne parte do caminho ambiental durante o script. Configuração inútil em 90% dos casos, a menos que você tenha arquivos com nomes semelhantes em vários locais de caminho que podem ficar travados, a menos que "NoWorkingDirectory" seja especificado.
Veja mais detalhes aqui.
Responder2
Resposta curta para usuários do Windows sem nenhum conhecimento de programação
Executar um executável com um (ou mais) nome(s) de diretório/arquivo passados como argumento(s) para o executável por meio de um item de menu de contexto do shell aberto clicando com o botão direito em um diretório ou arquivo (no lado direito de umExplorador de arquivos do Windowsjanela) resulta na inicialização do executável com o diretório de trabalho atual definido para este executável com
- o diretório que contém o diretório/arquivo clicado sem nenhum valor de registro
NoWorkingDirectory
presente
ou - o diretório
C:\Windows\System32
ou mais precisamente%SystemRoot%\system32
com o valor de registroNoWorkingDirectory
presente no registro do Windows.
Muitos executáveis e scripts codificados que não são bons exigem que a primeira variante com o diretório de trabalho atual seja definido como o diretório que contém o diretório ou arquivo a ser processado. Essa é a razão pela qual a primeira variante é o padrão.
Em alguns casos, a primeira variante causa um comportamento indesejado, como executar cmd.exe
para processar um script em lote que recebe o nome do diretório/arquivo clicado como argumento e o diretório/arquivo é referenciado usando seuCaminho UNC.
A segunda variante NoWorkingDirectory
presente no registro do Windows pode ser usada para todos os executáveis e scripts codificados realmente bons.
Resposta longa para usuários e programadores do Windows interessados em detalhes
A biblioteca do kernel do Windows contém a funçãoCriarProcessoque é usado por explorer.exe
e pela maioria dos outros executáveis capazes de executar outro executável sem ou com umINFORMAÇÕES DE INICIALIZAÇÃOestrutura para iniciar um executável do Windows. Um dos parâmetros da função CreateProcess
é lpCurrentDirectory
– um ponteiro longo para a string com o caminho do diretório para definir como diretório de trabalho atual para o processo criar. O valor do ponteiro também pode ser nulo para instruir CreateProcess
a usar o diretório atual do processo que está chamando CreateProcess
como diretório de trabalho atual para o processo criar. A maioria dos executáveis chama CreateProcess
com um ponteiro nulo para o parâmetro da função lpCurrentDirectory
.
OExplorador de arquivos do Windows( explorer.exe
) chama CreateProcess
com o caminho do diretório que contém o diretório/arquivo no qual o usuário clicou com o botão do dispositivo apontador secundário (geralmente direito) (geralmente do mouse) e clicou no menu de contexto aberto no item, resultando na inicialização de um executável com o clicado nome do diretório/arquivo como argumento.
O valor da string do registro NoWorkingDirectory
altera o comportamento de como explorer.exe
as chamadas CreateProcess
relacionadas ao parâmetro de função lpCurrentDirectory
. O diretório atual é sempre o diretório do sistema do Windows com este valor de string de registro presente, ou seja, o diretório %SystemRoot%\System32
que na maioria das máquinas Windows se expande para C:\Windows\System32
.
Isso pode ser visto da seguinte forma:
Por favor abra umprompt de comandojanela e execute os seguintes 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"
As duas reg
linhas de comando são adicionadas ao registro do 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\""
O comando md
e as quatro echo
linhas de comando criam o arquivo em lote C:\Temp\DirTest\DirTest.cmd
com as seguintes linhas de comando:
@echo Batch file started with: %0 %*
@echo Current directory is: "%CD%"
@echo Command line used is: %CMDCMDLINE%
@pause
Agora comeceExplorador de arquivos do Windowsse ainda não estiver em execução e navegue no lado esquerdo da árvore de pastas até o diretório C:\Windows\System32\drivers
. Clique com o botão direito do mouseno lado direitona pasta etc
e clique com o botão esquerdo no menu de contexto aberto no itemNenhum teste de diretório de trabalhoacabei de adicionar antes ao registro do Windows.
O arquivo em lote recém-criado é executado e exibido em uma janela do console:
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"
A primeira linha de saída mostra o diretório atual definido CreateProcess
começando cmd.exe
com os quatro argumentos de acordo com a string passada lpCurrentDirectory
pelo processo pai explorer.exe
. Pode-se ver que oExplorador de arquivos do Windowschamado CreateProcess
neste caso com C:\Windows\System32\drivers
o caminho do diretório de trabalho atual.
A segunda linha de saída mostra com quais argumentos o arquivo em lote foi iniciado, incluindo o argumento 0, que é a string usada para referenciar o arquivo em lote adicionado ao registro do Windows.
A terceira linha mostra como cmd.exe
ela mesma foi iniciada, explorer.exe
respectivamente CreateProcess
. cmd.exe
embora armazenado no registro sem entorno, "
esteja incluído "
ao ser iniciado por explorer.exe
.
O valor da string do registro NoWorkingDirectory
não existe no momento. Essa é a razão pela qual o diretório de trabalho atual cmd.exe
está definido C:\Windows\System32\drivers
como o diretório atual ao explorer.exe
clicar com o botão direitono lado direitona pasta etc
com a pasta atualmente ativa emExplorador de arquivos do Windowsser C:\Windows\System32\drivers
.
Agora clique com o botão direito emExplorador de arquivos do Windows no lado esquerdona árvore de pastas do diretório C:\Windows
enquanto a pasta atualmente ativa ainda está C:\Windows\System32\drivers
e clique com o botão esquerdo no menu de contexto no itemNenhum teste de diretório de trabalho.
Há mais uma janela do console aberta exibindo as seguintes linhas:
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"
A segunda e a terceira linha são as esperadas. Mas o diretório atual não é nem C:\Windows\System32\drivers
nem C:\
e também não C:\Windows
. Portanto, pode-se observar que iniciar um executável com o diretório que contém um diretório nem sempre funciona como esperado quando o usuário clica com o botão direito na árvore de pastas no lado esquerdo de um diretório ou pasta de shell virtual.
Também pode ser visto que o caminho do diretório de trabalho atual não é nem mesmo o caminho real do diretório do sistema Windows, como neste caso seria exibido C:\Windows\System32
e não C:\WINDOWS\system32
. Observe as diferenças no caso de algumas letras. O caminho do diretório do sistema Windows realmente usado aqui é uma concatenação do valor do registro SystemRoot
em key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion
que possui o valor da string C:\WINDOWS
concatenado com a string fixa \system32
. O caminho real do diretório é C:\Windows\System32
.
Um arquivo em lote ou executável ou qualquer outro script projetado para ser executado por explorer.exe
programas semelhantes ou por meio de um item de menu de contexto deve sempre levar em consideração que o diretório atual pode ser um diretório completamente diferente do diretório que contém o(s) nome(s) de diretório/arquivo passado(s) . A chamada do processo CreateProcess
define qual diretório é o diretório atual do processo criado.
cmd.exe
tem um comportamento especial ao ser iniciado com o caminho do diretório atual sendo um caminho UNC. Ele altera o diretório atual, neste caso, para %SystemRoot%
(diretório do Windows) e exibe as informações:
\\ComputerName\SharedFolder\Resource
CMD.EXE foi iniciado com o caminho acima como o diretório atual.
Os caminhos UNC não são suportados. Padrão para diretório do Windows.
Isso é feito cmd.exe
para compatibilidade com versões anteriores porque muitos executáveis não estão sendo executados corretamente no caminho do diretório atual, não começando com uma letra de unidade e dois pontos.
É possível executar em uma janela de prompt de comando:
reg add "HKCU\Software\Microsoft\Command Processor" /v DisableUNCCheck /t REG_DWORD /d 1 /f
Isso desativa a verificação da Convenção de Nomenclatura Universal (UNC) para sessões de comando e cmd.exe
aceita também um diretório atual com um caminho UNC.
Ok, de volta ao valor do registro NoWorkingDirectory
. Execute em uma janela de prompt de comando agora:
reg add "HKCU\Software\Classes\Directory\shell\NoWorkingDirectoryTest" /v NoWorkingDirectory /t REG_SZ
É adicionado o valor da string do registro NoWorkingDirectory
sem valor. Portanto, o registro contém agora:
[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\""
Observe a terceira linha adicional ausente na saída do registro postada acima.
EmExplorador de arquivos do Windowsclique com o botão direitono lado esquerdono diretório C:\Windows
com a pasta atualmente ativa parada C:\Windows\System32\drivers
e clique com o botão esquerdo no item do menu de contextoNenhum teste de diretório de trabalhoexatamente como feito antes. A saída é novamente como antes. Portanto, não há alteração para este caso de uso.
Clique com o botão direito em próximono lado direitoemExplorador de arquivos do Windowsno diretório etc
e C:\Windows\System32\drivers
clique com o botão esquerdo no item do menu de contextoNenhum teste de diretório de trabalho. Uma janela do console é aberta mostrando as seguintes linhas:
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"
A primeira linha mostra a diferença importante com o valor da string de registro NoWorkingDirectory
presente, que é agora C:\WINDOWS\system32
em vez de C:\Windows\system32\drives
antes. O diretório de trabalho atual agora é sempre o diretório do sistema Windows definido com %SystemRoot%\system32
.
Não importa se NoWorkingDirectory
é adicionado ao registro sem um valor de string ou com um valor de string como C:\Windows
. Pode até ser adicionado um valor de registro do tipo DWORD
com nome NoWorkingDirectory
com valor 0
ou 1
. O tipo de valor de registro NoWorkingDirectory
e seu valor não importam para o shell do Windows ( explorer.exe
). Só importa se existe um valor de registro de nome NoWorkingDirectory
presente ou não no registro do Windows na chave usada para a extensão do shell.
A chave de registro adicionada e o arquivo em lote podem ser usados para mais análises, como navegar até um recurso de rede usando um caminho UNC ou clicar com o botão direito em uma pasta de shell virtual no lado esquerdo da árvore de pastas. Também pode ser criado C:\Temp\DirTest
um diretório com nome Development & Test(!) 100%
e passar o nome dessa pasta com caminho completo para um arquivo em lote ou executável ou outro script e ver o que acontece. Muitos arquivos em lote não conseguem processar corretamente uma sequência de argumentos, como "C:\Temp\DirTest\Development & Test(!) 100%"
por causa de espaços, pontos de exclamação, colchetes e um sinal de porcentagem, embora seja um nome de diretório válido que consiste apenas em caracteres ASCII.
A chave de registro e o arquivo em lote, bem como o diretório criado usado para demonstrar o comportamento devem ser excluídos finalmente executando os seguintes comandos na janela do prompt de comando após fechar todas as janelas do console abertas executando DirTest.cmd
:
reg delete "HKCU\Software\Classes\Directory\shell\NoWorkingDirectoryTest" /f
del C:\Temp\DirTest\DirTest.cmd
rd C:\Temp\DirTest
rd C:\Temp
Observação:Muitas das propriedades de um arquivo de atalho com extensão de arquivo .lnk
definem os valores passados porExploradoratravés CreateProcess
de seus parâmetros de função e da estrutura STARTUPINFO
. Por exemplo a propriedadeComeçardefine o valor da string para o qual lpCurrentDirectory
finalmente aponta ao usar o arquivo de atalho para iniciar um executável.
Uma nota para programadores:
- O C#Classe de processoé uma classe wrapper C# para
CreateProcess
. - O Javaclasse ProcessBuilderestá no Windows uma classe wrapper Java para
CreateProcess
. - O Pítonmódulo de subprocessoestá no Windows um módulo wrapper Python para
CreateProcess
. - O comando do Processador de Comandos do Windows
start
suporta opções que são todas passadas aoCreateProcess
usácmd.exe
-las, como a opção/D
que define a string passada paraCreateProcess
usar o parâmetro de funçãolpCurrentDirectory
.
Toda linguagem de programação e script com suporte para execução de um executável no Windows possui uma função ou classe que chama o Windows CreateProcess
sem ou com STARTUPINFO
estrutura.
Responder3
A propriedade do verbo "NoWorkingDirectory" não está documentada, então isso é apenas um palpite:
Cmd.exe não oferece suporte a compartilhamentos remotos (UNC) como o diretório atual e se você iniciar o Cmd.exe com esse diretório de trabalho, ele imprimirá uma mensagem de aviso no console.
Se você observar o registro "Abrir janela de comando aqui", verá que ele inicia o Cmd.exe com o pushd
comando e pushd
oferece suporte a caminhos UNC. NoWorkingDirectory existe apenas para evitar a exibição de uma mensagem de aviso.
Não é realmente necessário para o PowerShell.