Windows 10 では、フォルダーまたはファイル エクスプローラーのバックグラウンドで Shift キーを押しながら右クリックすると、コンテキスト メニューに「OpenPowerShell window here」コマンドが追加されます。
'
ただし、PowerShell ウィンドウを開くために使用されるコマンドは、フォルダー名に埋め込み文字が含まれないことを誤って想定している点で、適切に定義されていません (少なくとも W10 リリース ID 1709 の時点では) 。
# !! Breaks with folder names such as "a'b"
powershell.exe -noexit -command Set-Location -literalPath '%V'
修正方法については以下を参照してください。ただし、管理者権限が必要であることに注意してください。
答え1
更新: スタンドアロン コマンド --- スクリプト ファイルに依存しません。
このコードをコピーして貼り付け、パワーシェル即時の「概念実証」デモ用のコンソール:
$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
- 結果のコマンドで
%%
リテラル シンボルを生成するには、2 つのパーセント記号 ( ) が必要であることに注意してください。%
マシン全体でコマンドを変更するには、レジストリを直接編集します。関連するキーは次のとおりです。
HKLM\SOFTWARE\Classes\Directory\Background\Shell\PowerShell\Command
HKLM\SOFTWARE\Classes\Directory\Shell\PowerShell\Command
値を編集して
(Default)
次のように変更します。powershell.exe -NoExit -Command &{Set-Location -LiteralPath $Args[1]} --%% %V
Full Control
ユーザーに追加した権限を削除します。所有権を取得するために実行した手順でユーザー名を
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の回避策としては、パワーシェルコマンドラインですが、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
これは、(ユーザーごとの mod)の下にコンテキスト メニュー エントリを作成する、上記のコードの「自己インストール」バージョンです。
- 次の内容を、
.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
序文
キース・ミラーの役に立つ回答実用的な自動化ソリューションです。注意すべき唯一の点は、ユーザーレベル。
以下の回答は、すべてのユーザーソリューションと技術的な背景については、
OpenHere.ps1
Keith の回答は、すべてのユーザー向けソリューションでも同様に使用できます (自己インストール部分を除く)。
敬意を表してレフェルチ彼のすべての意見に感謝します。
注記:
- この修正管理者権限が必要(ランニング標高付き)。
開ける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
注記:
を介して呼び出すことにより
cmd
、Windows PowerShell ではなく、後者のコンソール設定が取得され、特に青い背景が含まれます。これを避けるに
start
は、powershell.exe
、 の新しい窓通常の設定と色で動作しますが、欠点は、必ず作成される元の一時的なウィンドウがcmd.exe
画面上で短時間点滅することです。キース・ミラーの回答代替案を提供するヘルパー
.ps1
スクリプト、直接呼び出しが可能になり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:"
、 どれの休憩。