2015-08-03 3 views
0

Я создал элемент контекстного меню Windows, чтобы выполнить команду powershell. Однако я не могу понять, как передать % 1 моему сценарию Powershell с экранированными кавычками.Добавление команды PowerShell в контекстное меню Windows (и правильное выполнение кавычек)

Текущая запись в реестре:

[HKEY_CLASSES_ROOT\*\shell\Share file on FTP\Command] 
@="cmd.exe /C nircmd elevate PowerShell -NoProfile -NoLogo -Command \"& {(dir \"%1\" | Copy-ToFTP -Destination Public.Screenshots).source | clip}\"" 

Выдает следующую ошибку при выборе файла через "Общий доступ к файлам на FTP" пункт контекстного меню:

dir : Cannot find path 'D:\Multimedia' because it does not exist. 
At line:1 char:5 
+ & {(dir D:\Multimedia Files\Pictures\HTPC\20150328_220120.jpg | Copy-ToOnedrive ... 
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    + CategoryInfo   : ObjectNotFound: (D:\Multimedia:String) [Get-ChildItem], ItemNotFoundException 
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand 

БОНУС В настоящее время я использую сторонний инструмент Nircmd, чтобы поднять подсказку Powershell (так как моя powershell co mmand нуждается в этом). Если возможно, я хотел бы использовать родную Windows, чтобы сделать это вместо этого (сохраняя мой код команды до одной строки, если это возможно) .... NOT after, создав сценарий Powershell PS1, который поднимает себя.

EDIT: Ниже строки кода «должны» работать .. Однако, вместо того, чтобы путь аа ShortName, я получаю неожиданный неправильный результат:

Я скопировать и вставить значение ключа реестра сделать его более удобным для чтения (вместо REG-содержимого файла)

cmd.exe /c for %%A in (%1) do @set I=%%~sA | PowerShell.exe -NoExit -NoProfile -NoExit -NoLogo -Command "& {(dir %I% | Copy-ToFTP -Destination Public.Screenshots).source | clip}" 

в конечном счете производит этот выход в Powershell:

dir : Cannot find path 'D:\Multimedia Files\Pictures\HTPC\:433310880:4624' 
 
because it does not exist.

+0

Я думаю, что на самом деле завинчивания меня является то, что *** % ~ s1 *** не работает под Windows 8.1 co mmand-interpreter, cmd. Я использовал эту технику сокращения в десятки раз под Win7 и ранее. Следовательно, даже самый простой пакетный файл с *** *** echo% ~ s1 *** возвращает полный путь без каких-либо сокращений или ошибок. – MKANET

+0

Я предполагаю, что сложность синтаксиса будет довольно сложной; или, я бы, наверное, уже видел рабочие ответы – MKANET

ответ

0

Как я могу проверить это является первым я создать рабочую пакетный файл. Обязательно избегайте всех полномочий, чтобы нормально работать при двойном щелчке командного файла. Затем, как только я могу заставить пакетный файл дважды щелкнуть правильно, я, наконец, скопирую его в раздел реестра с помощью графического интерфейса, так что графический интерфейс автоматически ускорит двойные кавычки, что происходит при экспорте настроек reg.

Значение Я не тестирую непосредственно из реестра, потому что здесь работает несколько уровней экранов.

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

start /wait /b powershell -command "Clear-Host;$CLIPBOARD = PowerShell -NoProfile -STA -Command {[reflection.assembly]::loadwithpartialname('PresentationCore') | Out-Null;[Windows.Clipboard]::GetText()};C:\Windows\Explorer.exe $CLIPBOARD" Как я могу получить настройки, связанные с реестром, я просто добавляю cmd/c в начало рабочего пакетного скрипта и вставляю непосредственно в раздел реестра, а затем экспортируем в .reg-файл. Причина в том, что у regedit.exe есть встроенная функция для выхода или двойного // все правильно и до тех пор, пока она работает из командного файла, вы можете обернуть ее «cmd/c», и она будет запущена. Я предпочитаю запуск/так что он остается достаточно продолжительным для тех типов команд, которые я запускаю, но во всех случаях это может не понадобиться. Вот что я получаю после экспорта в .reg-файл.

(Найдено источник моего примера)

https://superuser.com/a/705188/281412

редактор системного реестра Windows версии 5.00

[HKEY_CLASSES_ROOT \ Directory \ Background \ Shell \ Open_in_Explorer] "MUIVerb" = "Open_in_Explorer_By_KNUCKLE_DRAGGER" "icon" = "Explorer.exe" "Position" = "Top" "Extended" = ""

[HKEY_CLASSES_ROOT \ Directory \ Background \ shell \ Open_in_Explorer \ command] @ = "cmd/c start/wait/b powershell -command \" Clear-Host; $ CLIPBOARD = PowerShell -NoProfile -STA -Command {[reflection.assembly ] :: loadwithpartialname ('PresentationCore') | Out-Null; [Windows.Clipboard] :: GetText()}; C: \ Windows \ Explorer.exe $ CLIPBOARD \ ""

Для больших скриптов вам понадобится команда base64, которая позволит избежать 100% эти проблемы (набор символов base64 не требует экранирования) и позволяет запускать многострочные скрипты из одной строки.

https://stackoverflow.com/a/24997890/3093031

Несколько примеров самовозвышение сценариев здесь.

Determine if script is running hidden

По какой-то причине у меня нет никаких кнопок в моем гуй, не может добавлять теги кода. Кому-то придется их редактировать.

Вы на 100% уверены, что не должны вызывать nircmdc.exe, версию командной строки nircmd ???

+0

Мне нужна помощь с моим синтаксисом; или, по крайней мере, рабочий пример ближе к тому, что я пытаюсь сделать. Все мои тесты сначала выполняются в пакетных файлах ... Включая использование% ~ s1 (упоминалось ранее)/который не работает под Win8. – MKANET

+0

Мне особенно нужна помощь в обработке *** «% 1» *** часть моего кода. – MKANET

+0

PS: Кроме того, насколько мне известно, интерпретатор cmd для Windows не имеет собственной кодировки символов base64. Другими словами, слишком поздно для base64 кодировать уже испорченную строку/переменную в Powershell. Это нужно сделать до того, как он перейдет в Powershell. Может, я недостаточно четко объяснил свою проблему? – MKANET

0

Я, наконец, выяснил проблему. Командный интерпретатор Windows, CMD, дампы % 1 для Powershell в качестве исходного скриптового блока. Командлеты Powershell, с которыми я тестировался, не могут автоматически использовать тип скриптового типа для типа строки (при его передаче). Из-за чего было сложно отлаживать то, что «% 1» (с кавычками вокруг него) DID сохраняет полный путь имени, который выглядит ИДЕНТИЧНЫ в нормальную строку с полным именем каталога пути, такие как:

% 1 = "D: \ Multimedia Files \ Pictures \ HTPC \ 20150328_220120.jpg"

Это может обмануть большинство людей в полагая, что это Строка. Фактически это рассматривается как скриптблок!

Ниже мое решение по моему вопросу. Кроме того, похоже, что мне не нужно было поднимать Powershell после этого для этого к. Надеюсь, кто-то в будущем может найти эту статью полезной; экономя их много времени.

ShareImageOneDrive.рег

Windows Registry Editor Version 5.00 
 

 
[HKEY_CLASSES_ROOT\*\shell\Share Image on OneDrive\Command] 
 
@="cmd.exe /c PowerShell.exe -NoProfile -WindowStyle Hidden -NoLogo -Command \"& {param ($I = {%1}) ; (Copy-ToOnedrive -Path $I.ToString() -Destination Public).source | clip}\""

реестра значение ключа (легче читать код)

cmd.exe /c PowerShell.exe -NoProfile -WindowStyle Hidden -NoLogo -Command "& {param ($I = {%1}) ; (Copy-ToOnedrive -Path $I.ToString() -Destination Public).source | clip}"