Выполнение скрипта PowerShell через контекстное меню проводника для элементов, содержащих амперсанд в своих именах

Выполнение скрипта PowerShell через контекстное меню проводника для элементов, содержащих амперсанд в своих именах

Я использую слегка измененную версию методики, приведенной вэтот ответдля создания пункта контекстного меню в проводнике Windows, который позволит мне запустить скрипт PowerShell для определенных папок.

Команда выглядит так:

cmd /K PowerShell "C:\PowerShellScript\folder_script.ps1 \"%1\" | clip" 

Это работает нормально, за исключением случаев, когда в имени папки есть амперсанд (&). Тогда я получаю следующую ошибку (целевая папка была названа Testing & Testing):

The string starting:
At line:1 char:37
+ C:\PowerShellScript\folder_script.ps1  <<<< "E:\tmp\Testing
is missing the terminator: ".
At line:1 char:53
+ E:\Dropbox\PowerShell\namefixer.ps1 "E:\tmp\Testing  <<<<
    + CategoryInfo          : ParserError: (E:\tmp\Testing :String) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : TerminatorExpectedAtEndOfString

Очевидно, что-то интерпретирует амперсанд как специальный символ, но я не знаю, как это исправить. Устранение амперсанда из имени папки для меня не является приемлемым решением.

Предпочтительным было бы решение, не требующее пакетного сценария.

Я использую Windows 7 Enterprise (64-разрядную) с PowerShell 2.

решение1

Вы можете использоватьдословный маркерPowershell: --%сообщает Powershell, что все, что следует за ним, не следует интерпретировать.

Таким образом, ваша команда будет выглядеть так:

cmd /K PowerShell "C:\PowerShellScript\folder_script.ps1 --% \"%1\" | clip" 

Если в именах файлов нет двойных кавычек, то все должно быть в порядке.

Этот маркер появился в Powershell 3.0 впервые, поэтому убедитесь, что он обновлен.

решение2

Вы можете попробовать изменить свой скрипт PowerShell. И изменить строку cmd на пакетный файл...

Ваш пакет (runner.cmd)

set ps_arg="%~1"
@cd /d %~dp0
PowerShell "folder_script.ps1 | clip"

Вторая строка означает, что папка, в которой находится файл runner.cmd, устанавливается как текущая папка, чтобы вы могли запустить скрипт PowerShell без полного пути. Это упрощает перемещение, поскольку вам не нужно редактировать файл runner.cmd.

И получите доступ к вашему пути с помощью следующего в вашем скрипте:

$value = $env:ps_arg -replace """",""

Кавычки из пакетного файла, по-видимому, передаются в скрипт PowerShell и должны быть удалены, отсюда и -replace """","". Поскольку двойные кавычки недопустимы в именах файлов Windows, это никогда не удалит ничего важного.

Итак, командная строка будет

cmd /K runner.cmd "%1"

решение3

Это проблема с кавычками. Замените экранированные двойные кавычки на экранированные одинарные кавычки, чтобы ваша команда выглядела так:

cmd /K PowerShell "C:\PowerShellScript\folder_script.ps1 \'%1\' | clip"

Вы используете две разные программы (cmd и powershell) и запускаете три разных фрагмента кода, которые могут принимать аргументы (cmd, powershell и скрипт .ps1).

cmd нужны три аргумента: /K Powershell и аргументы для powershell. Аргументы для powershell должны быть одной строкой, поэтому они заключены в кавычки.

Powershell нужен один аргумент: командная строка, которую вы хотите выполнить.

Скрипту .ps1 нужен аргумент: папка для запуска. Powershell должен интерпретировать путь как одну строку, поэтому его нужно заключить в кавычки.

При запуске команды cmd запускает Powershell и отправляет ему строку в кавычках с развернутой переменной и без кавычек или экранирующих символов:C:\PowerShellScript\folder_script.ps1 "Testing & Testing" | clip

Кавычки гарантируют, что скрипт увидит один аргумент вместо трех.

(Я не уверен, почему разные типы цитат давали разные результаты (насколько мне известно, они не должны были давать разные результаты), но они давали, когда я тестировал, поэтому я предоставил решение, которое работало в моей системе. Если вы предоставите больше подробностей, я, возможно, смогу предложить решение, которое подойдет и вам.)

Связанный контент