The solution is using in Window registry file:
@="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\")"
This results in following command line in Windows registry:
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")
Important is Windows command processor option /V:ON
which enables delayed expansion for environment variables as explained by help output on running in a command prompt window cmd /?
. Option /V:ON
must be specified left to option /C
(close after execution of command line) respectively /K
(keep command process running after execution of command line) because everything after /C
or /K
is interpreted as part of the command line to execute.
The usage of /K
instead of /C
makes it possible to see what happens on execution of this command line and set url
can be executed by the user after the command line execution finished to see what is the final value of environment variable url
.
The help output on running in a cmd window set /?
explains when and how to use delayed environment variable expansion. It must be used if an environment variable is defined or modified on a command line and referenced on same command line as it is here the case with single line with multiple commands. It is also necessary if an environment variable is defined or modified within a command block starting with (
and ending with matching )
because of cmd.exe
parses the entire command block and replaces all %variable%
references by current value of reference environment variable before executing any command of this command block or left to begin of command block on same command line.
See also How does the Windows Command Interpreter (CMD.EXE) parse scripts?
It is necessary to reference environment variables with !variable!
to expand this reference delayed after having enabled delayed expansion.
Note: Every exclamation mark in command line is interpreted as begin/end of delayed expanded environment variable reference once being enabled even inside a double quoted argument string.
A commented batch file with (nearly) same code would be:
@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