更新:獨立命令 --- 沒有腳本檔案依賴性。

更新:獨立命令 --- 沒有腳本檔案依賴性。

在 Windows 10 中,按住 Shift 鍵並右鍵點選資料夾或檔案總管的背景,會在上下文功能表中新增「在此處開啟 PowerShell 視窗」指令。

但是,用於開啟 PowerShell 視窗的命令定義不明確(至少從 W10 版本 ID 1709 開始),因為它錯誤地假設資料夾名稱從不包含嵌入'字元:

# !! Breaks with folder names such as "a'b"
powershell.exe -noexit -command Set-Location -literalPath '%V' 

請參閱下面的修復程序,但請注意,它需要管理權限。

答案1

更新:獨立命令 --- 沒有腳本檔案依賴性。

複製、貼上並在 a 中執行此程式碼電源外殼用於即時「概念驗證」演示的控制台:

$msg = @'
$Args[0] : {0}
$Args[1] : {1}
'@
&{echo ($msg -f $Args[0], $Args[1])} --% I'm an unquoted string with an apostrophe and spaces.

輸出:

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:\>
  • (有趣的是,它既--%是功能性的,也是作為參數捕獲的)

「神奇的子彈」是停止解析令牌: --%。根據文件:

PowerShell 3.0 中引入的停止解析符號 (--%) 指示 PowerShell 避免將輸入解釋為 PowerShell 指令或表達式。
……
當遇到停止解析符號時,PowerShell 會將行中的剩餘字元視為文字。

雖然旨在與可執行檔的參數一起使用,但它也可以與腳本區塊的參數一起使用,如上面的程式碼所示。

因此,要使用不含引號的路徑執行Set-Location,語法為:

    &{Set-Location -LiteralPath $Args[1]} --% <unquoted path>  

因此我們的註冊表命令變為:

    powershell.exe -NoExit -Command &{Set-Location -LiteralPath $Args[1]} --%% %V  
  • %%請注意,需要使用雙百分號 ( ) 才能%在結果指令中產生文字符號。

若要在電腦範圍內修改命令,請直接編輯登錄機碼。相關的鍵是:

  • HKLM\SOFTWARE\Classes\Directory\Background\Shell\PowerShell\Command
  • HKLM\SOFTWARE\Classes\Directory\Shell\PowerShell\Command
  1. 掌握鑰匙並賦予自己完全控制權

  2. 編輯該(Default)值,將其變更為:

     powershell.exe -NoExit -Command &{Set-Location -LiteralPath $Args[1]} --%% %V  
    
  3. 刪除Full Control您為使用者新增的權限。

  4. TrustedInstaller透過NT Service\TrustedInstaller在您取得所有權的步驟中指定使用者名稱來將所有者變更回。

若要針對每個使用者修改命令,只需建立並編輯登錄項目:

  • HKCU\Softwar\Classes\Directory\Background\Shell\PowerShell\Command

  • HKCU\Software\Classes\Directory\Shell\PowerShell\Command
    將的值更改(Default)為:

     powershell.exe -NoExit -Command &{Set-Location -LiteralPath $Args[1]} --%% %V  
    

或只是複製、貼上並執行以下命令:

'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
}


原始回覆

對於 5.1 的解決方法,我想不出一個方法電源外殼命令行,但呼叫單行腳本似乎可以解決問題:

(根據 @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"
###
  • 另存為“OpenHere.ps1”到適當的位置
  • 然後您可以修改:
    • HKLM\SOFTWARE\Classes\Directory\Shell\PowerShell\Command
      如果您具有管理員存取權限並且能夠輕鬆處理所有權和權限。
      否則,您可以在以下位置建立每個使用者條目:
    • HKCU\Software\Classes\Directory\Shell\PowerShell\Command

註冊表命令行的語法是:

  • powershell.exe -noexit -File "C:\Path\to\OpenHere.ps1" "%V"

這是上述程式碼的“自安裝”版本,它將在HKCU(每用戶模式)下建立上下文選單條目。

  • 將以下內容儲存為.ps1檔案並保存在其所在目錄中。
  • 從以下位置執行腳本電源外殼沒有參數的控制台。該程式碼.ps1在其建立的命令列中使用檔案的當前 Path\FileName 。
### 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

答案2

前言

  • 基斯·米勒的實用回答是一個務實的自動化解決方案 - 唯一需要注意的是它僅適用於使用者等級

  • 以下答案可能會引起您的興趣全部用戶解決方案和技術背景; Keith 的答案OpenHere.ps1同樣可以用於所有使用者的解決方案(自安裝部分除外)。


帽子尖到萊斯·費奇對於他的所有投入。

筆記:

  • 這個修復需要管理權限(跑步有海拔)。

打開regedit.exe應用以下步驟兩個都以下註冊表​​項HKEY_CLASSES_ROOT\Directory\shell\Powershell\command
HKEY_CLASSES_ROOT\Directory\Background\shell\Powershell\command

  • 準備:修改權限以便可以修改該值(PowerShell 指令):

    • 手動修改權限的替代方案:

      • @LesFerch 提到以下第三方實用程式:備擇方案手動權限修改,允許您regedit.exe直接以NT SERVICE\TrustedInstaller使用者身分執行:

        動力運行(我的首選),高級運行。這是比搞亂權限(人們經常出錯並破壞東西)更安全的選擇。

      • 基斯·米勒的實用回答提到定義使用者級鍵作為替代方案 - 不需要提升,但將解決方案限制為目前用戶

    • 右鍵單擊command子項目並選擇Permissions...

    • 點擊Advanced和:

      • 使該Administrators組成為擁有者關鍵的
      • Administrators團隊完全控制密鑰
    • 注意:我不知道這些修改有任何不利影響,但如果您知道任何不利影響,請告訴我們。
      但是,為了安全起見,您可以在修改命令後恢復這些修改,如下所述,這需要將TrustedInstaller安全主體還原為金鑰的擁有者command;請注意,您必須將其指定為
      NT SERVICE\TrustedInstaller.

  • 現在將command鍵的(Default)值替換為以下內容(請參閱下面有關控制台設定/顏色的註釋):

    cmd /c set "_dir=%V%" & powershell.exe -NoExit -Command Set-Location -LiteralPath $env:_dir
    
    • 筆記:

      • 透過呼叫 via cmd,您將獲得後者的控制台設置,而不是 Windows PowerShell 的控制台設置,其中特別包括藍色背景。

        • start您可以透過放置before來避免這種情況powershell.exe,這會打開一個新窗戶具有通常的設定和顏色,但缺點是創建的原始瞬態視窗總是cmd.exe在螢幕上短暫閃爍。

        • 基斯·米勒的回答提供了一種替代方案幫助.ps1腳本,允許直接調用via powershell.exe -File,從而避免了閃爍問題;這-File 命令列介面參數對待它的參數字面上地,所以下面描述的使用時的問題-Command不適用。

          powershell.exe -NoExit -File "C:\Path\to\OpenHere.ps1" "%V"
          
      • 呼喚透過cmd /c是個最堅固的安全的選項:

        • 如果的值包含字符,則它%V只能在語法上破壞命令,而根據定義,這是不可能的(文件和資料夾名稱不能包含)。set""

        • 但是,如果資料夾名稱包含看起來像cmd.exe環境變數引用的內容逐字(例如%OS%引用的變數存在,引用被擴展,導致對該資料夾的變更失敗或 - 假設 - 將不同的資料夾作為目標。

        • cd該命令不能僅用作呼叫的一部分的原因cmd.exe是,powershell.exe從名稱恰好包含[](例如foo[0])的資料夾呼叫時會發生故障。此錯誤已在PowerShell(核心)7+CLI,pwsh.exe因此您可以簡單地使用:

          # PowerShell 7+
          cmd /c cd /d "%V" & pwsh.exe
          
          • 其實pwsh.exe是新的-WorkingDirectory參數使能直接的呼叫(這不僅更有效率,而且還避免了控制台設定問題):[1]

            pwsh.exe -WorkingDirectory "%V\."
            
      • 打電話時powershell.exe直接一個選項,它總是涉及權衡:

        • 如果您的資料夾名稱可能包含文字'字符,但從不包含文字`$字符,則可以使用"..."可擴展的(插值)字串) 相反,但這帶有以下內容 警告:

          • 雖然該命令只是簡單地故障逐字資料夾名稱,例如foo`bar$foo(或 - 假設 - 目標不同的目錄),這可能會導致不需要的命令執行,透過精心惡意製作的包含$(...)子表達式的資料夾名稱。

            powershell.exe -NoExit -Command "Set-Location -LiteralPath \"%V\""
            

應該可以編寫上述步驟的腳本。


[1]\.是為了確保諸如此類的路徑C:\也得到了妥善處理;否則,PowerShell CLI 會(合理地)將 解釋"C:\"C:跟著一個逃脫了 "字符,即實際上是逐字 C:", 哪個休息

相關內容