Как сделать замену строки для переменной в командной строке Windows? - PullRequest
1 голос
/ 27 мая 2019

Был ли способ выполнить замену строки в командной строке, а не внутри командного файла?

Небольшая предыстория: Некоторое время назад мне нужно было зарегистрировать собственный протокол URI, который будет пересылатьвызванный URL в Chrome через взлом реестра, который привел к:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CNX]
@="Chrome HTML Document"
"URL Protocol"=""

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CNX\DefaultIcon]
@="C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe,0"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CNX\shell]

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CNX\shell\open]

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CNX\shell\open\command]
<b>@="cmd /c cd \"C:\\Program Files (x86)\\Google\\Chrome\\Application\\\" & FOR /f \"tokens=1-3delims=?#\" %%a IN (\"%1\") DO (if \"%%a#%%b%%c\"==\"%1\" (chrome.exe %1) else (chrome.exe %%a#%%c%%b) )"</b>

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Internet Explorer\ProtocolExecute\CNX]
"WarnOnOpen"=dword:00000000

Проблема, которую я заметил сейчас, заключается в том, что через какое-то новое обновление Windows то, что раньше вызывалось как

cnx:// www.someurl.com

в IE теперь превращается в

cnx://<b>%20</b>www.someurl.com

при выполнении команды.

Поэтому мне интересно, есть ли способ где-нибудь заменить строку и полностью удалить cnx://%20 из моей переменной %%a или что-то еще?

Но все мои попыткииспользование https://ss64.com/nt/syntax-replace.html не сработало.Было бы здорово услышать или прочитать, что это вообще невозможно, поэтому я могу перестать крутить колеса.

1 Ответ

1 голос
/ 28 мая 2019

Решение использует файл реестра Windows:

@="cmd.exe /V:ON /C cd /D \"C:\\Program Files (x86)\\Google\\Chrome\\Application\\\" & set \"url=%1\" & set \"url=!url:cnx://%%20=!\" & set \"url=!url:cnx://=!\" & for /F \"tokens=1-3 delims=?#\" %%a in (\"!url!\") do if \"%%a#%%b%%c\"==\"!url!\" (chrome.exe \"!url!\") else (chrome.exe \"%%a#%%c%%b\")"

Это приводит к следующей командной строке в реестре Windows:

cmd.exe /V:ON /C cd /D "C:\Program Files (x86)\Google\Chrome\Application\" & set "url=%1" & set "url=!url:cnx://%%20=!" & set "url=!url:cnx://=!" & for /F "tokens=1-3 delims=?#" %%a in ("!url!") do if "%%a#%%b%%c"=="!url!" (chrome.exe "!url!") else (chrome.exe "%%a#%%c%%b")

Важным является параметр командного процессора Windows /V:ON, которыйразрешает отложенное расширение для переменных среды, как объясняется выводом справки при запуске в окне командной строки cmd /?.Опция /V:ON должна быть указана слева от опции /C (закрытие после выполнения командной строки) соответственно /K (оставить процесс выполнения команд после выполнения командной строки), поскольку все, что после /C или /K интерпретируется как частькомандной строки для выполнения.

Использование /K вместо /C позволяет увидеть, что происходит при выполнении этой командной строки, а set url может быть выполнен пользователем после командыВыполнение строки завершено, чтобы узнать, каково окончательное значение переменной среды url.

Вывод справки при запуске в окне cmd set /? объясняет, когда и как использовать отложенное расширение переменной среды.Он должен использоваться, если переменная среды определена или изменена в командной строке и указана в той же командной строке, что и в случае с одной строкой с несколькими командами .Это также необходимо, если переменная среды определена или изменена в командном блоке, начиная с ( и заканчивая сопоставлением ), поскольку cmd.exe анализирует весь командный блок и заменяет все ссылки %variable% на текущее значение ссылкиПеременная среды перед выполнением любой команды этого командного блока или слева от начала командного блока в той же командной строке.

См. также Как интерпретатор сценариев команд Windows (CMD.EXE) анализирует сценарии?

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

Примечание. Каждый восклицательный знак в командной строке интерпретируется как начало / конец отложенногорасширенная ссылка на переменную среды после включения даже внутри строки аргумента в двойных кавычках.

Комментированный пакетный файл с (почти) тем же кодом будет выглядеть так:

@echo off
rem Explicitly enable command extensions although enabled by default
rem and delayed environment variable expansion disabled by default.
setlocal EnableExtensions EnableDelayedExpansion

rem Change current directory to directory containing Google Chrome browser.
cd /D "%ProgramFiles(x86)%\Google\Chrome\Application\"

rem Define environment variable url with value of first
rem argument with surrounding double quotes removed.
set "url=%~1"

rem Exit batch file if called without any argument or with just "".
if not defined url goto EndBatch

rem Remove case-insensitive all occurrences of string "cnx://"
rem with an additional percent encoded space from the url argument.
set "url=!url:cnx://%%20=!"

rem Remove case-insensitive all occurrences of string "cnx://".
set "url=!url:cnx://=!"

rem Split up the url strings on question mark and hash and assign just
rem first three ?# delimited substrings to loop variables a, b and c.
rem FOR would not run any command in command block on url starting with
rem a semicolon. Run Google Chrome with the url if first substring with #
rem and the two other substrings appended is case-sensitive equal the url.
rem Otherwise run Google Chrome with redefined url with second and third
rem substring exchanged after first substring and hash character.
for /F "tokens=1-3 delims=?#" %%a in ("!url!") do (
    if "%%a#%%b%%c" == "!url!" (
        start "" chrome.exe "!url!"
    ) else (
        start "" chrome.exe "%%a#%%c%%b"
    )
)

rem Restore initial environment on calling the batch file which means
rem discarding all environment variables defined or modified in block
rem above like environment variable url, restore initial current directory
rem as it was before using command CD and restore also initial states of
rem command extensions (most likely enabled) and delayed expansion (most
rem likely disabled).
:EndBatch
endlocal
...