No Windows 10, clicar com o botão direito do mouse em uma pasta ou em segundo plano no File Explorer adiciona um comando “Abra a janela do PowerShell aqui” ao menu de contexto.
No entanto, o comando usado para abrir a janela do PowerShell está mal definido (pelo menos a partir do ID de versão 1709 do W10), pois assume incorretamente que os nomes das pastas nunca contêm '
caracteres incorporados:
# !! Breaks with folder names such as "a'b"
powershell.exe -noexit -command Set-Location -literalPath '%V'
Veja abaixo uma correção, mas observe que ela requer privilégios administrativos.
Responder1
Atualização: um comando independente --- sem dependência de arquivo de script.
Copie, cole e execute este código em umPowerShellconsole para uma demonstração instantânea de "prova de conceito":
$msg = @'
$Args[0] : {0}
$Args[1] : {1}
'@
&{echo ($msg -f $Args[0], $Args[1])} --% I'm an unquoted string with an apostrophe and spaces.
Saída:
PS C:\> $msg = @'
>> $Args[0] : {0}
>> $Args[1] : {1}
>> '@
>> &{echo ($msg -f $Args[0], $Args[1])} --% I'm an unqoted string with an apostroohe and spaces.
$Args[0] : --%
$Args[1] : I'm an unqoted string with an apostroohe and spaces.
PS C:\>
- (interessante que
--%
é funcional e capturado como argumento)
A “bala mágica” é aPare de analisar o token: --%
. De acordo com a documentação:
O símbolo de parada de análise (--%), introduzido no PowerShell 3.0, orienta o PowerShell a abster-se de interpretar a entrada como comandos ou expressões do PowerShell.
...
Quando encontra um símbolo de parada de análise, o PowerShell trata os caracteres restantes na linha como literais.
Embora destinado ao uso com argumentos para executáveis, ele também funciona com argumentos para blocos de script, como demonstra o código acima.
Então, para executar Set-Location
com um caminho sem aspas, a sintaxe é:
&{Set-Location -LiteralPath $Args[1]} --% <unquoted path>
E assim nosso comando de registro se torna:
powershell.exe -NoExit -Command &{Set-Location -LiteralPath $Args[1]} --%% %V
- Observe que o sinal de porcentagem duplicado (
%%
) é necessário para produzir o%
símbolo literal no comando resultante.
Para modificar o comando em toda a máquina, edite o registro diretamente. As chaves relevantes são:
HKLM\SOFTWARE\Classes\Directory\Background\Shell\PowerShell\Command
HKLM\SOFTWARE\Classes\Directory\Shell\PowerShell\Command
Assuma a propriedade da chave e atribua a si mesmo o controle total.
Edite o
(Default)
valor, alterando-o para:powershell.exe -NoExit -Command &{Set-Location -LiteralPath $Args[1]} --%% %V
Remova a
Full Control
permissão que você adicionou para seu usuário.Altere o proprietário
TrustedInstaller
especificandoNT Service\TrustedInstaller
o nome de usuário nas etapas que você seguiu para assumir a propriedade.
Para modificar o comando por usuário, basta criar e editar as chaves de registro:
HKCU\Softwar\Classes\Directory\Background\Shell\PowerShell\Command
HKCU\Software\Classes\Directory\Shell\PowerShell\Command
Alterando o valor de(Default)
para:powershell.exe -NoExit -Command &{Set-Location -LiteralPath $Args[1]} --%% %V
ou apenas copie, pasee e execute o seguinte:
'Background\','' | ForEach{
$splat = @{
'Path' = ('HKCU:\Software\Classes\Directory\{0}Shell\PowerShell\Command' -f $_)
'Value' = 'powershell.exe -NoExit -Command &{Set-Location -LiteralPath $Args[1]} --%% %V'
}
New-Item @splat -Force
}
Resposta original
Para uma solução alternativa 5.1, não consigo pensar em uma maneira com apenas umPowerShelllinha de comando, mas chamar um script de uma linha parece funcionar:
(Edição/melhoria de código de acordo com o comentário de @ mklement0)
### OpenHere.ps1
Set-Location -LiteralPath $Args[0]
### (HKCU|HKLM)\Software\Classes\Direcory[\Background]\Shell\PowerShell\Command
###
###powershell.exe -noexit -File "C:\Path\to\OpenHere.ps1" "%V"
###
- Salve como "OpenHere.ps1" em um local apropriado
- Você pode então modificar:
HKLM\SOFTWARE\Classes\Directory\Shell\PowerShell\Command
se você tiver acesso de administrador e se sentir confortável em lidar com propriedade e permissões.
Caso contrário, você pode criar entradas por usuário em:HKCU\Software\Classes\Directory\Shell\PowerShell\Command
A sintaxe da linha de comando do registro é:
powershell.exe -noexit -File "C:\Path\to\OpenHere.ps1" "%V"
Aqui está uma versão de "instalação automática" do código acima que criará as entradas do menu de contexto em HKCU
(mod por usuário).
- Salve o seguinte como um
.ps1
arquivo no diretório onde ele residirá. - Execute o script a partir de umPowerShellconsole sem argumentos. O código usa o Path\FileName atual do
.ps1
arquivo na linha de comando que ele cria.
### OpenHere.ps1
If ($Args) { ### Launched from context menu
Set-Location -LiteralPath $Args[0]
} Else { ### Create HKCU registry entries
'Background\','' | ForEach {
$splat = @{
'Path' = ('HKCU:\Software\Classes\Directory\{0}Shell\PowerShell\Command' -f $_)
'Value' = ('powershell.exe -NoExit -File "{0}" "%V"' -f $PSCommandPath)
'Type' = 'ExpandString'
}
New-Item @splat -Force
}
}
### The "(Default)" value is created as a REG_EXPAND_SZ to allow for subsequent
### editing that can include environmental variables
Responder2
Prefácio
Resposta útil de Keith Milleré uma solução pragmática e automatizada - a única coisa a notar é que ela só funciona nonível de usuário.
A resposta abaixo pode ser interessante para umtodos os usuáriossolução e para formação técnica; a
OpenHere.ps1
resposta de Keith pode igualmente ser usada em uma solução para todos os usuários (exceto para a parte de instalação automática).
Ponta do chapéu paraLesFerchpor todas as suas contribuições.
Observação:
- Esta correçãorequer privilégios administrativos(correndocom elevação).
Aberto regedit.exe
eaplique os seguintes passos paraambosdas seguintes chaves de registro: HKEY_CLASSES_ROOT\Directory\shell\Powershell\command
e
HKEY_CLASSES_ROOT\Directory\Background\shell\Powershell\command
:
Preparação:modificar as permissõespara que a modificação do valor (o comando do PowerShell) seja possível:
Alternativas para modificação manual de permissão:
@LesFerch menciona os seguintes utilitários de terceiros comoalternativasà modificação manual de permissão, permitindo que você execute
regedit.exe
diretamente comoNT SERVICE\TrustedInstaller
usuário:Power Run(meu preferido),Execução Avançada. Esta é uma opção muito mais segura do que mexer nas permissões (que muitas vezes as pessoas erram e quebram as coisas).
Resposta útil de Keith Millermenciona definiçãonível de usuáriochaves como alternativa - o que não requer elevação, mas limita a solução aousuário atual.
Clique com o botão direito na
command
subchave e selecionePermissions...
Clique
Advanced
e:- faça do
Administrators
grupo oproprietárioda chave - dê ao
Administrators
grupo controle total da chave
- faça do
Observação: não tenho conhecimento de quaisquer efeitos adversos dessas modificações, mas informe-nos se souber de algum.
No entanto, por segurança, você pode reverter essas modificações após modificar o comando conforme descrito abaixo, o que implica restaurar aTrustedInstaller
entidade de segurança como proprietária dacommand
chave; observe que você deve especificá-lo como
NT SERVICE\TrustedInstaller
.
Agora substitua o valor
command
da chave(Default)
pelo seguinte (veja a nota sobre configurações/cores do console abaixo):cmd /c set "_dir=%V%" & powershell.exe -NoExit -Command Set-Location -LiteralPath $env:_dir
Observação:
Ao chamar via
cmd
, você obterá as configurações do console deste último em vez das do Windows PowerShell, que incluem principalmente um fundo azul.Você pode evitar isso colocando
start
beforepowershell.exe
, que abre umanova janelacom as configurações e cores usuais, mas a desvantagem é que a janela original e transitória que é invariavelmente criadacmd.exe
pisca brevemente na tela.A resposta de Keith Milleroferece uma alternativa através de um
.ps1
script auxiliar, que permite a invocação diretapowershell.exe -File
e, portanto, evita o problema de flashing; o-File
CLIparâmetro trata seus argumentosliteralmente, portanto, o problema descrito abaixo ao usar-Command
não se aplica.powershell.exe -NoExit -File "C:\Path\to\OpenHere.ps1" "%V"
Chamandoatravés da
cmd /c
é omais robustoeseguroopção:O valor de
%V
só poderia quebrar sintaticamente oset
comando se contivesse"
caracteres, o que é por definição impossível (nomes de arquivos e pastas não podem conter"
).No entanto, se o nome de uma pasta contiver algo parecido com uma
cmd.exe
referência de variável de ambienteliteralmente(por exemplo%OS%
)ea variável referenciada existe, a referência é expandida, fazendo com que a mudança para essa pasta falhe ou - hipoteticamente - uma pasta diferente seja direcionada.A razão pela qual o comando não pode ser usado apenas
cd
como parte dacmd.exe
chamada é quepowershell.exe
funciona mal quando chamado de uma pasta cujo nome contém[
ou]
(por exemplofoo[0]
, ). Este bug foi corrigido noPowerShell (núcleo) 7+CLI,pwsh.exe
, então você poderia simplesmente usar:# PowerShell 7+ cmd /c cd /d "%V" & pwsh.exe
Na verdade,
pwsh.exe
é novo-WorkingDirectory
parâmetro permitediretoinvocação (isso não é apenas mais eficiente, mas também evita o problema de configurações do console): [1]pwsh.exe -WorkingDirectory "%V\."
Ao ligar
powershell.exe
diretamenteéuma opção, envolve invariavelmentecompensações:Se os nomes das suas pastas podem conter
'
caracteres literais, mas NUNCA contêm caracteres`
ou literais$
, você pode usar"..."
(umexpansível(interpolando) string) em vez disso, mas isso vem com o seguinte EMBARGO:Embora o comando simplesmentedefeituosocom nomes de pastas literais, como
foo`bar
ou$foo
(ou - hipoteticamente - direcionar umdiferentediretório), isso pode resultar emexecução indesejada de comandos, por meio de nomes de pastas cuidadosamente elaborados com códigos maliciosos que contêm$(...)
subexpressões.powershell.exe -NoExit -Command "Set-Location -LiteralPath \"%V\""
Deve ser possível criar o script das etapas acima.
[1]\.
está anexado para garantir queraizcaminhos como esses C:\
também são tratados adequadamente; caso contrário, a CLI do PowerShell interpretaria (justificadamente) "C:\"
, por exemplo, comoC:
seguido por umescapou "
caráter, ou seja, com efeito comoliteralmente C:"
, qualrompe.