Как обойтись без переменной "%~dp0"

vavun

Постоянный участник
Сообщения
117
Реакции
50
Здравствуйте ;)

Обнаружил на форуме такую замечательную вещь, как поиск в интернете из контекстного меню проводника

Решил подправить под себя, а именно добавить иконки для удобства. Иконки добавлены, но возник вопрос: на сколько опасно использовать переменную %~dp0 , и какие есть выходы и альтернативы ?


Код:
@set @x=0; /*
@echo off
SetLocal EnableExtensions DisableDelayedExpansion
set "live=%USERPROFILE%"

REG ADD "HKCR\AllFilesystemObjects\Shell" /f >nul 2>&1 || if "%~2" neq "Admin" (
  echo Для установки надстройки требуются повышенные права.
  cscript.exe //nologo //e:jscript "%~f0"& Exit /B) else (echo Вы не обладаете необходимыми привилегиями& pause& Exit /B
)

:begin
cls
echo. Введите цифру и нажмите { ENTER }
echo.
echo. Установить:
echo.
echo 1. Поиск в Google
echo 2. Поиск в Yandex
echo.
set /p "ch=Ваш выбор: "

::Первая часть VBS
for /f "delims=[]" %%N in ('find /n ":UnpackVBS" ^<"%~f0"') do set /a num=%%N
more +%num% >"%live%\KozaN.vbs" <"%~f0"

::Вторая часть VBS
if "%ch%"=="1" (
  set VerbName=Найти в "Google"
  >> "%live%\KozaN.vbs" echo CreateObject^("WScript.Shell"^).Run "explorer ""https://google.ru/search?ie=UTF-8&hl=ru&q=" ^& Arg ^& """"
  REG ADD "HKCR\AllFilesystemObjects\Shell\CopyAsPath"  /v Icon  /t REG_SZ /d "%USERPROFILE%\google.ico" /f
  1>nul copy "%~dp0"google.ico %USERPROFILE% /y
)

if "%ch%"=="2" (
  set VerbName=Найти в "Яндекс"
  >> "%live%\KozaN.vbs" echo CreateObject^("WScript.Shell"^).Run "explorer ""http://yandex.ru/yandsearch?text=" ^& Arg ^& """"
  REG ADD "HKCR\AllFilesystemObjects\Shell\CopyAsPath"  /v Icon  /t REG_SZ /d "%USERPROFILE%\yandex.ico" /f
  1>nul copy "%~dp0"yandex.ico %USERPROFILE% /y
)

if not Defined VerbName goto begin

REG ADD "HKCR\AllFilesystemObjects\Shell\CopyAsPath" /f
REG ADD "HKCR\AllFilesystemObjects\Shell\CopyAsPath"  /ve  /t REG_SZ /d "%VerbName%" /f
REG ADD "HKCR\AllFilesystemObjects\Shell\CopyAsPath\command" /f
REG ADD "HKCR\AllFilesystemObjects\Shell\CopyAsPath\command" /ve /d "wscript.exe //nologo \"%live%\KozaN.vbs\" \"%%1\"" /f

echo.
echo Установка завершена.
echo.
echo "SafeZone.cc"
echo.
pause
Exit /B

*/try {
  var ShellApp = new ActiveXObject('Shell.Application');
  ShellApp.ShellExecute ('cmd.exe', '/c ""' + WScript.ScriptFullName + '" "" "Admin"','','runas',1);
} catch (e) { }/*

:UnpackVBS
  On Error Resume Next
  if WScript.Arguments.Count = 0 then WScript.Quit
  Arg = WScript.Arguments(0)
  Arg = Mid(Arg, InStrRev(Arg, "\") + 1)
  Arg = Replace(Arg, " ", "%20")
  set ShellApp = CreateObject("Shell.Application")'*/


ЗЫ код рабочий, иконки с соответствующими названиями лежат в папке со скриптом

Спасибо.
 
Спасибо за модернизацию.
google.png
yandex.png

По моему вполне безопасно.
 
По моему вполне безопасно.
Я тоже не вижу причин для паники, но автор скрипта сказал, что лучше немного подправить, у меня нет причин ему не доверять.

В разделе bat/cmd есть образцы контроля уровня доступа и элевации uac ,логика: контроль запуска,если права повышенные то перезапускаем скрипт с пониженными,что дает возможность спокойно определить местоположение папки,закрепить файл с адресом в нужном каталоге.
А когда надо повысить привелегии читаем путь из созданного ранее файла с последующим удалением.

В частности этот момент интересует.Ладно, поставим вопрос по другому: при каких обстоятельствах переменная %~dp0 может принять неверное значение ?
будь то на примере этого скрипта, или любого другого ?
 
vavun, проверил на компе,все нормально-нет проблем с иконкой.
Видимо было недопонимание с обоюдной стороны.
Обновлю ресурс.
 
Koza Nozdri, при запуске от администратора он вообще не стартует, паузы уже во все возможные места прописывал, при обычном запуске, он успешно делает элевацию и находит иконки.
Кстати ваш оригинал тоже, только сайчас проверил
 
Последнее редактирование:
vavun, добрый вечер !

Ошибка в неверном расположении кавычки:
1>nul copy "%~dp0"google.ico %USERPROFILE% /y
а должно быть
1>nul copy "%~dp0google.ico" "%USERPROFILE%" /y

%~dp0 - папка расположения батника. Всегда заканчивается обратным слешем.

Ладно, поставим вопрос по другому: при каких обстоятельствах переменная %~dp0 может принять неверное значение ?
%~dp0 не раскроется, если ее указать в консоле (не в батнике).
Но это не имеет отношения к данной теме.

В предостережении говорилось о другой переменной %cd%. Это текущая папка.
При подтверждении элевации прав она сменяется на %SystemRoot%\System32.
При этом изначально рабочий каталог может быть каким угодно, а не только папка расположения батника
(например, можно задать в свойствах ярлыка к батнику или через параметры API-шной функции ShellExecute (в VBS есть аналог)).
 
Dragokas, почему после первого запуска "неправильного" скрипта отказывают абсолютно все батники при запуске через ПКМ-админ?
 
Koza Nozdri, из-за знака & в пути к батнику.
Похоже нормального пути решения проблемы нет. Баг ловит сам обработчик ассоциации винды.
Придется переименовать папку.
 
А у меня вобще все батники погасли...буду разбираться)
из-за знака & в пути к батнику.
Похоже нормального пути решения проблемы нет. Баг ловит сам обработчик ассоциации винды.
Придется переименовать папку.
А вернуть как было мне как?А все) разобрался.
Ресурс обновлю ща.
 
Последнее редактирование:
из-за знака & в пути к батнику
+

Без & работает от админа. Там, где не ждали ...
В предостережении говорилось о другой переменной %cd%
Стало быть возникает вопрос: как сохранить значение переменной %cd% полученное до элевации ?

Только если записать его куда-либо, верно ?
 
Не используйте %cd%. Зачем Вам путь к рабочему каталогу?
Или Вам ради интереса?

Если запускаете правой кнопкой "от имени администратора", то исходный рабочий каталог уже никак не узнаете.
Его изменит программа consent.exe, отвечающая за вызов диалога UAC и создание дочерних процессов.
Пользуйтесь %~dp0 - это всегда путь к папке, откуда вызван батник.
______________________________

Похоже нормального пути решения проблемы нет. Баг ловит сам обработчик ассоциации винды.
Да. Так и есть.

Как видим, в режиме повышенных привилегий, вызов батника осуществляется с явным указанием приложения-обработчика cmd.exe
Видимо того требует consent.exe, иначе ей не будет понятно, какое приложение вызывать.

cmd_bug.png


Проблема в том, что дяди из M$ в спешке прописали часто используемый ими повсеместно в реестре "шаблон" %1 %*
думая, что здесь все тоже самое "пройдет", но в cmd очень особый парсер аргументов.
Читать свою же справку им лень:

cmd_syntax.png


В результате получаем вот такой перехват "падающего" окна консоли:

bug_intercept.png


search.png


А всего то нужно добавить кавычки к ассоциации. Вот так:
%SystemRoot%\System32\cmd.exe /C ""%1" %*"

Либо воспользоваться таким фиксом:
Код:
Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\cmdfile\shell\runas\command]
@=hex(2):25,00,53,00,79,00,73,00,74,00,65,00,6d,00,52,00,6f,00,6f,00,74,00,25,\
  00,5c,00,53,00,79,00,73,00,74,00,65,00,6d,00,33,00,32,00,5c,00,63,00,6d,00,\
  64,00,2e,00,65,00,78,00,65,00,20,00,2f,00,43,00,20,00,22,00,22,00,25,00,31,\
  00,22,00,20,00,25,00,2a,00,22,00,00,00

После этого запуск любых батников со спецсимволами в имени или пути
через контекстное меню "от имени администратора" больше не будет приводить к "падению".
И конечно все тоже самое нужно выполнить с подразделом
HKEY_CLASSES_ROOT\batfile\shell\runas\command
 
Последнее редактирование:
Назад
Сверху Снизу