Qual é o significado do valor da string “NoWorkingDirectory” no Registro do Windows?

Qual é o significado do valor da string “NoWorkingDirectory” no Registro do Windows?

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.

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

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

  1. o diretório que contém o diretório/arquivo clicado sem nenhum valor de registro NoWorkingDirectorypresente
    ou
  2. o diretório C:\Windows\System32ou mais precisamente %SystemRoot%\system32com o valor de registro NoWorkingDirectorypresente 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.exepara 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 NoWorkingDirectorypresente 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.exee 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 CreateProcessa usar o diretório atual do processo que está chamando CreateProcesscomo diretório de trabalho atual para o processo criar. A maioria dos executáveis ​​chama CreateProcesscom um ponteiro nulo para o parâmetro da função lpCurrentDirectory.

OExplorador de arquivos do Windows( explorer.exe) chama CreateProcesscom 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 NoWorkingDirectoryaltera o comportamento de como explorer.exeas chamadas CreateProcessrelacionadas 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%\System32que 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 reglinhas 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 mde as quatro echolinhas de comando criam o arquivo em lote C:\Temp\DirTest\DirTest.cmdcom 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 etce 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 CreateProcesscomeçando cmd.execom os quatro argumentos de acordo com a string passada lpCurrentDirectorypelo processo pai explorer.exe. Pode-se ver que oExplorador de arquivos do Windowschamado CreateProcessneste caso com C:\Windows\System32\driverso 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.exeela mesma foi iniciada, explorer.exerespectivamente CreateProcess. cmd.exeembora armazenado no registro sem entorno, "esteja incluído "ao ser iniciado por explorer.exe.

O valor da string do registro NoWorkingDirectorynão existe no momento. Essa é a razão pela qual o diretório de trabalho atual cmd.exeestá definido C:\Windows\System32\driverscomo o diretório atual ao explorer.execlicar com o botão direitono lado direitona pasta etccom 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:\Windowsenquanto a pasta atualmente ativa ainda está C:\Windows\System32\driverse 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\driversnem 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\System32e 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 SystemRootem key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersionque possui o valor da string C:\WINDOWSconcatenado 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.exeprogramas 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 CreateProcessdefine qual diretório é o diretório atual do processo criado.

cmd.exetem 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.exepara 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.exeaceita 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 NoWorkingDirectorysem 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:\Windowscom a pasta atualmente ativa parada C:\Windows\System32\driverse 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 etce C:\Windows\System32\driversclique 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 NoWorkingDirectorypresente, que é agora C:\WINDOWS\system32em vez de C:\Windows\system32\drivesantes. 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 DWORDcom nome NoWorkingDirectorycom valor 0ou 1. O tipo de valor de registro NoWorkingDirectorye seu valor não importam para o shell do Windows ( explorer.exe). Só importa se existe um valor de registro de nome NoWorkingDirectorypresente 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\DirTestum 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 .lnkdefinem os valores passados ​​porExploradoratravés CreateProcessde seus parâmetros de função e da estrutura STARTUPINFO. Por exemplo a propriedadeComeçardefine o valor da string para o qual lpCurrentDirectoryfinalmente 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 startsuporta opções que são todas passadas ao CreateProcessusá cmd.exe-las, como a opção /Dque define a string passada para CreateProcessusar o parâmetro de função lpCurrentDirectory.

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 CreateProcesssem ou com STARTUPINFOestrutura.

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 pushdcomando e pushdoferece 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.

informação relacionada