In Windows 10 wird durch Klicken mit gedrückter Umschalttaste und Rechtsklick auf einen Ordner oder im Hintergrund im Datei-Explorer dem Kontextmenü der Befehl „PowerShell-Fenster hier öffnen“ hinzugefügt.
Der zum Öffnen des PowerShell-Fensters verwendete Befehl ist jedoch (zumindest seit W10-Release-ID 1709) insofern schlecht definiert, als er fälschlicherweise davon ausgeht, dass Ordnernamen niemals eingebettete '
Zeichen enthalten:
# !! Breaks with folder names such as "a'b"
powershell.exe -noexit -command Set-Location -literalPath '%V'
Eine Lösung finden Sie weiter unten. Beachten Sie jedoch, dass hierfür Administratorrechte erforderlich sind.
Antwort1
Update: Ein eigenständiger Befehl – keine Abhängigkeit von Skriptdateien.
Kopieren Sie diesen Code, fügen Sie ihn ein und führen Sie ihn aus in einemPower ShellKonsole für eine sofortige „Proof-of-Concept“-Demo:
$msg = @'
$Args[0] : {0}
$Args[1] : {1}
'@
&{echo ($msg -f $Args[0], $Args[1])} --% I'm an unquoted string with an apostrophe and spaces.
Ausgabe:
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:\>
- (interessant, dass das
--%
sowohl funktional ist als auch als Argument erfasst wird)
Das „Wundermittel“ ist dieToken-Analyse beenden: --%
. Gemäß der Dokumentation:
Das in PowerShell 3.0 eingeführte Symbol zum Beenden der Analyse (--%) weist PowerShell an, Eingaben nicht als PowerShell-Befehle oder -Ausdrücke zu interpretieren.
...
Wenn PowerShell auf ein Symbol zum Beenden der Analyse stößt, behandelt es die verbleibenden Zeichen in der Zeile als Literal.
Obwohl es für die Verwendung mit Argumenten für ausführbare Dateien vorgesehen ist, funktioniert es auch mit Argumenten für Skriptblöcke, wie der obige Code zeigt.
Für die Ausführung Set-Location
mit einem Pfad ohne Anführungszeichen lautet die Syntax also:
&{Set-Location -LiteralPath $Args[1]} --% <unquoted path>
Und somit wird unser Registrierungsbefehl:
powershell.exe -NoExit -Command &{Set-Location -LiteralPath $Args[1]} --%% %V
- Beachten Sie, dass das doppelte Prozentzeichen (
%%
) erforderlich ist, um das Literalsymbol%
im resultierenden Befehl zu erzeugen.
Um den Befehl maschinenweit zu ändern, bearbeiten Sie die Registrierung direkt. Die relevanten Schlüssel sind:
HKLM\SOFTWARE\Classes\Directory\Background\Shell\PowerShell\Command
HKLM\SOFTWARE\Classes\Directory\Shell\PowerShell\Command
Übernehmen Sie den Besitz des Schlüssels und sichern Sie sich die volle Kontrolle.
Bearbeiten Sie den
(Default)
Wert und ändern Sie ihn wie folgt:powershell.exe -NoExit -Command &{Set-Location -LiteralPath $Args[1]} --%% %V
Entfernen Sie die
Full Control
Berechtigung, die Sie für Ihren Benutzer hinzugefügt haben.Ändern Sie den Besitzer zurück zu, indem Sie in den Schritten, die Sie zum Übernehmen des Besitzers befolgt haben, als Benutzernamen
TrustedInstaller
angeben .NT Service\TrustedInstaller
Um den Befehl für jeden Benutzer einzeln zu ändern, erstellen und bearbeiten Sie einfach die Registrierungsschlüssel:
HKCU\Softwar\Classes\Directory\Background\Shell\PowerShell\Command
HKCU\Software\Classes\Directory\Shell\PowerShell\Command
Ändern des Wertes von(Default)
in:powershell.exe -NoExit -Command &{Set-Location -LiteralPath $Args[1]} --%% %V
oder kopieren, einfügen und führen Sie einfach Folgendes aus:
'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
}
Ursprüngliche Antwort
Für einen 5.1-Workaround fällt mir keine Möglichkeit ein, mit nur einemPower ShellBefehlszeile, aber der Aufruf eines einzeiligen Skripts scheint zu funktionieren:
(Codebearbeitung/-verbesserung gemäß Kommentar von @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"
###
- Speichern Sie es als „OpenHere.ps1“ an einem geeigneten Ort.
- Sie können dann Folgendes ändern:
HKLM\SOFTWARE\Classes\Directory\Shell\PowerShell\Command
wenn Sie über Administratorzugriff verfügen und mit dem Umgang mit Eigentumsrechten und Berechtigungen vertraut sind.
Andernfalls können Sie Einträge pro Benutzer unter folgendem Pfad erstellen:HKCU\Software\Classes\Directory\Shell\PowerShell\Command
Die Syntax für die Registrierungsbefehlszeile lautet:
powershell.exe -noexit -File "C:\Path\to\OpenHere.ps1" "%V"
Hier ist eine „selbstinstallierende“ Version des obigen Codes, die die Kontextmenüeinträge unter HKCU
(Benutzermod) erstellt.
- Speichern Sie Folgendes als
.ps1
Datei in dem Verzeichnis, in dem es gespeichert wird. - Führen Sie das Skript aus einemPower ShellKonsole ohne Argumente. Der Code verwendet den aktuellen Pfad\Dateinamen der
.ps1
Datei in der erstellten Befehlszeile.
### 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
Antwort2
Vorwort
Keith Millers hilfreiche Antwortist eine pragmatische, automatisierte Lösung - allerdings funktioniert sie nur auf derBenutzerlevel.
Die folgende Antwort könnte für einenAlle NutzerLösung und für den technischen Hintergrund; die
OpenHere.ps1
Informationen aus Keiths Antwort können gleichermaßen in einer Lösung für alle Benutzer verwendet werden (mit Ausnahme des selbstinstallierenden Teils).
Tipp des Hutes anAbonnierenfür all seine Beiträge.
Notiz:
- Dieser Fixerfordert Administratorrechte(läuftmit Erhöhung).
Offen regedit.exe
undFühren Sie die folgenden Schritte aus, umbeideder folgenden Registrierungsschlüssel: HKEY_CLASSES_ROOT\Directory\shell\Powershell\command
Und
HKEY_CLASSES_ROOT\Directory\Background\shell\Powershell\command
:
Vorbereitung:Ändern Sie die Berechtigungensodass eine Änderung des Wertes (des PowerShell-Befehls) möglich wird:
Alternativen zur manuellen Berechtigungsänderung:
@LesFerch nennt die folgenden Dienstprogramme von Drittanbietern alsAlternativenzur manuellen Berechtigungsänderung, indem Sie Folgendes
regedit.exe
direkt alsNT SERVICE\TrustedInstaller
Benutzer ausführen können:PowerRun(mein Favorit),Erweiterter Lauf. Dies ist eine viel sicherere Option, als mit Berechtigungen herumzuspielen (was die Leute oft falsch machen und Dinge kaputt machen).
Keith Millers hilfreiche Antworterwähnt DefinitionBenutzerlevelTasten als Alternative - die keine Erhöhung erfordert, aber die Lösung auf dieaktueller Benutzer.
Klicken Sie mit der rechten Maustaste auf den
command
Unterschlüssel und wählen SiePermissions...
Klicken Sie auf
Advanced
und:- machen die
Administrators
Gruppe zumEigentümerdes Schlüssels - Geben Sie der
Administrators
Gruppe die volle Kontrolle über den Schlüssel
- machen die
Hinweis: Mir sind keine negativen Auswirkungen dieser Änderungen bekannt, aber teilen Sie uns dies bitte mit, wenn Ihnen welche bekannt sind.
Aus Sicherheitsgründen können Sie diese Änderungen jedoch rückgängig machen, nachdem Sie den Befehl wie unten beschrieben geändert haben. Dabei wird derTrustedInstaller
Sicherheitsprinzipal als Eigentümer descommand
Schlüssels wiederhergestellt. Beachten Sie, dass Sie ihn als angeben müssen
NT SERVICE\TrustedInstaller
.
Ersetzen Sie nun den Wert
command
des Schlüssels(Default)
durch Folgendes (siehe Hinweis zu Konsoleneinstellungen/Farben unten):cmd /c set "_dir=%V%" & powershell.exe -NoExit -Command Set-Location -LiteralPath $env:_dir
Notiz:
Durch den Aufruf über
cmd
erhalten Sie die Konsoleneinstellungen der letzteren anstelle der Windows PowerShell, die insbesondere einen blauen Hintergrund aufweisen.Sie können dies vermeiden, indem Sie
start
vor platzierenpowershell.exe
, wodurch einneues Fenstermit den üblichen Einstellungen und Farben, aber der Nachteil besteht darin, dass das ursprüngliche, vorübergehende Fenster, das unweigerlich erstellt wird,cmd.exe
kurz auf dem Bildschirm aufblitzt.Keith Millers Antwortbietet eine Alternative über eineHilfsskript
.ps1
, das den direkten Aufruf über ermöglichtpowershell.exe -File
und somit das Flashing-Problem vermeidet; die-File
Befehlszeilenschnittstelle (CLI)Parameter behandelt seine Argumentebuchstäblich-Command
, daher besteht das unten beschriebene Problem bei der Verwendung nicht.powershell.exe -NoExit -File "C:\Path\to\OpenHere.ps1" "%V"
Berufungüber
cmd /c
ist derrobustesteUndsicherMöglichkeit:Der Wert von könnte den Befehl
%V
nur dann syntaktisch unterbrechen , wenn er Zeichen enthielte, was per Definition unmöglich ist (Datei- und Ordnernamen dürfen keine enthalten ).set
"
"
Wenn ein Ordnername jedoch etwas enthält, das wie eine
cmd.exe
Umgebungsvariablenreferenz aussiehtwörtlich(z.B%OS%
)UndDie referenzierte Variable ist vorhanden und die Referenz wird erweitert, wodurch der Wechsel zu diesem Ordner entweder fehlschlägt oder - hypothetisch - ein anderer Ordner als Ziel ausgewählt wird.Der Grund, warum der Befehl nicht einfach
cd
als Teil descmd.exe
Aufrufs verwendet werden kann, ist, dasspowershell.exe
er nicht funktioniert, wenn er aus einem Ordner aufgerufen wird, dessen Name zufällig[
oder enthält]
(z. B.foo[0]
). Dieser Fehler wurde behoben inPowerShell (Core) 7+CLI,pwsh.exe
also können Sie dort einfach Folgendes verwenden:# PowerShell 7+ cmd /c cd /d "%V" & pwsh.exe
Tatsächlich
pwsh.exe
ist es neu-WorkingDirectory
Parameter aktiviertDirekteAufruf (das ist nicht nur effizienter, sondern vermeidet auch das Problem mit den Konsoleneinstellungen): [1]pwsh.exe -WorkingDirectory "%V\."
Beim
powershell.exe
direkten AnrufIsteine Option, es beinhaltet immerKompromisse:Wenn Ihre Ordnernamen wörtliche
'
Zeichen enthalten können, aber NIEMALS wörtliche`
oder$
Zeichen enthalten, können Sie"..."
(einerweiterbar(interpolierende) Zeichenfolge), aber dies hat den folgenden Nachteil VORBEHALT:Während der Befehl einfachFehlfunktionmit wörtlichen Ordnernamen wie
foo`bar
oder$foo
(oder - hypothetisch - Ziel einandersVerzeichnis), kann es zuungewollte Ausführung von Befehlen, über sorgfältig – in böswilliger Absicht – erstellte Ordnernamen, die$(...)
Unterausdrücke enthalten.powershell.exe -NoExit -Command "Set-Location -LiteralPath \"%V\""
Es sollte möglich sein, die obigen Schritte per Skript zu erledigen.
[1] \.
ist so beigefügt, dass sichergestellt ist, dassWurzelPfade wie C:\
werden ebenfalls ordnungsgemäß behandelt. Andernfalls würde die PowerShell-CLI (zu Recht) "C:\"
beispielsweise so interpretieren, als C:
ob einentkam "
Charakter, d.h. in der Tat alswörtlich C:"
, welchegeht kaputt.