Update: Ein eigenständiger Befehl – ​​keine Abhängigkeit von Skriptdateien.

Update: Ein eigenständiger Befehl – ​​keine Abhängigkeit von Skriptdateien.

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-Locationmit 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
  1. Übernehmen Sie den Besitz des Schlüssels und sichern Sie sich die volle Kontrolle.

  2. Bearbeiten Sie den (Default)Wert und ändern Sie ihn wie folgt:

     powershell.exe -NoExit -Command &{Set-Location -LiteralPath $Args[1]} --%% %V  
    
  3. Entfernen Sie die Full ControlBerechtigung, die Sie für Ihren Benutzer hinzugefügt haben.

  4. Ändern Sie den Besitzer zurück zu, indem Sie in den Schritten, die Sie zum Übernehmen des Besitzers befolgt haben, als Benutzernamen TrustedInstallerangeben .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 .ps1Datei 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 .ps1Datei 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.ps1Informationen 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.exeundFühren Sie die folgenden Schritte aus, umbeideder folgenden Registrierungsschlüssel: HKEY_CLASSES_ROOT\Directory\shell\Powershell\commandUnd
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.exedirekt als NT SERVICE\TrustedInstallerBenutzer 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 commandUnterschlüssel und wählen SiePermissions...

    • Klicken Sie auf Advancedund:

      • machen die AdministratorsGruppe zumEigentümerdes Schlüssels
      • Geben Sie der AdministratorsGruppe die volle Kontrolle über den Schlüssel
    • 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 der TrustedInstallerSicherheitsprinzipal als Eigentümer des commandSchlüssels wiederhergestellt. Beachten Sie, dass Sie ihn als angeben müssen
      NT SERVICE\TrustedInstaller.

  • Ersetzen Sie nun den Wert commanddes 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 cmderhalten Sie die Konsoleneinstellungen der letzteren anstelle der Windows PowerShell, die insbesondere einen blauen Hintergrund aufweisen.

        • Sie können dies vermeiden, indem Sie startvor platzieren powershell.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.exekurz auf dem Bildschirm aufblitzt.

        • Keith Millers Antwortbietet eine Alternative über eineHilfsskript.ps1, das den direkten Aufruf über ermöglicht powershell.exe -Fileund 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übercmd /cist derrobustesteUndsicherMöglichkeit:

        • Der Wert von könnte den Befehl %Vnur 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.exeUmgebungsvariablenreferenz 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 cdals Teil des cmd.exeAufrufs verwendet werden kann, ist, dass powershell.exeer 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.exealso können Sie dort einfach Folgendes verwenden:

          # PowerShell 7+
          cmd /c cd /d "%V" & pwsh.exe
          
          • Tatsächlich pwsh.exeist es neu-WorkingDirectoryParameter aktiviertDirekteAufruf (das ist nicht nur effizienter, sondern vermeidet auch das Problem mit den Konsoleneinstellungen): [1]

            pwsh.exe -WorkingDirectory "%V\."
            
      • Beim powershell.exedirekten 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`baroder $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.

verwandte Informationen