I want to launch a windows executable from a batch file where the path to the executable is stored in a variable.
#echo off
set qtpath=C:\Program Files\Qt\5.7\mingw53_32\bin
set execpath=%qtpath%\windeployqt.exe
echo %execpath%
%execpath% --someparams
Unfortunately executing my script throws an error:
'C:\Program' is not recognized as an internal or external command, operable program or batch file.
Looks like somehow the string gets terminated at the space in Program Files.
You should change your code to this:
#echo off
set "qtpath=C:\Program Files\Qt\5.7\mingw53_32\bin"
set "execpath=%qtpath%\windeployqt.exe"
echo "%execpath%"
"%execpath%" --someparams
The SPACE, like also TAB, ,, ;, =, VTAB (vertical tabulator, ASCII 0x0B), FF (form-feed, ASCII 0x0C) and NBSP (non-break space, ASCII 0xFF) constitute token separators in the command prompt cmd. To escape tokenisation enclose your path in between "". This avoids also trouble with special characters like ^, ( and ), &, <, > and |.
The quotation marks in the set command lines again avoid trouble with special characters; they do not become part of the variable value because they enclose the entire assignment expression. Note that this syntax requires the command extensions to be enabled, but this is the default anyway.
I recommend not to include the quotation marks into variable values (set VAR="some value"), because then you could run into problems particularly when concatenating strings due to unwanted (double-)quotation (for instance, echo "C:\%VAR%\file.txt" returns "C:\"some value"\file.txt").
You are perfectly right. If the path to the file you want to execute contains spaces, you have to surround it with quotation marks:
#echo off
set qtpath=C:\Program Files\Qt\5.7\mingw53_32\bin
set execpath="%qtpath%\windeployqt.exe"
echo %execpath%
%execpath% --someparams
This should work.
It will also work when you surround %execpath% with quotation marks:
"%execpath%" --someparams
Related
In cmd I'm trying to do something like
program.exe -command "otherprogram.exe %thing% %path%"
The issue I'm having is that I can't figure out how to escape the % characters when they're inside double quotes, but I need the double quotes because of the spaces in this argument. Basically I don't want cmd to do variable expansion before passing the argument value to program.exe.
Just to be clear, this is directly in cmd, not in a batch script.
A simple semi solution is:
program.exe -command ^"otherprogram.exe %th^ing% %pa^t^h%^"
The positions of the carets inside the variable name are random.
This still could fail, but only for the rare case, if variables exists named thi^ng or pa^t^h
It seems strange, but don't escape the percent signs. Put a caret (the escape sign for every other special char) anywhere within the variable name: echo %^username% or `echo %use^rname%.
The first parsing removes the ^ (because there is (hopefully) no variable with that name). On command line (other than in a batch file), an empty variable doesn't show nothing, but the variable name including the surrounding %'s.
Any further level of parsing then receives the "normal" variable and expands it. Prove:
echo %usern^ame%
call echo %usern^ame%
Not your question, but for the sake of completeness: in a batch script, simply escape the % with another %:
echo %%username%%
call echo %%username%%
I have a variable with html code (having major, minor symbols)
and I need it to be exported and appended to a txt
set WORD1=^<p^>^<strong^>PROBLEM^</strong^> with something;n^</p^>
I can't echo the variable like this
echo %WORD1%
And I need to export it/append it to a file. I used:
echo %WORD1% >body.txt
But this generates an error as the variable has minor/Major symbol
If I double quote the variable, the exported text is exported with double quotes (and obviusly this is not what i need)
To define the variable, use:
set "WORD1=<p><strong>PROBLEM</strong> with something;n</p>"
To "export" the variable, use:
(
set /P "=%WORD1%"
echo/
) > body.txt < NUL
To define a variable in a safe way you need to enclose the whole assignment expression in quotation marks:
set "WORD1=<p><strong>PROBLEM</strong> with something;n</p>"
This avoids the need of escaping, unless the string itself contains quotation marks on its own.
Note that this syntax only works with command extensions enabled, but this is the default in Command Prompt anyway.
To return/expand an arbitrary string in a safe manner, even when it contains quotation marks on its own, is to use delayed variable expansion:
echo(!WORD1!
To safely write the output to a file, place the redirection expression at the front:
> "body.txt" echo(!WORD1!
You can also do this on one line:
set "WORD1=<p><strong>PROBLEM</strong> with something;n</p>"&&>body.txt cmd/v/cecho.!WORD1!
rem :: Or, without defining a previous variable, if it is not necessary:
>body.txt <nul set/P "=<p><strong>PROBLEM</strong> with something;n</p>"
I'm having a problem where I can't get all characters (especially special characters) to show when I try to echo them
echo 1234567890q!w#e#r$t%y^u&io()pa;s/d.f,ghjklzxcvb nmQAZXSWEDCVFRTGBNHYUJMKIOLP
When using this code in batch, it doesn't show the characters (especially the special characters) but instead say "This program is not recognizable as an internal or external command, operable program or batch file.". The reason to why this is saying this is because the lines have special characters but how do I show the special characters in echo on? Thanks people.
Neither of those lines results in that particular error message when I test them from the command line (although the first results in "Environment variable 123456etc. not defined"). You have properly quoted your "variable=value" pair, and there is no problem setting CHARSET to that value.
I suspect the problem is that when you echo %charset% the & is being evaluated as a command separator, and evaluating the string thereafter as a new command. Try retrieving the value of CHARSET in the delayed expansion style.
set "charset=1234567890q!w#e#r$t%%y^u&io()pa;s/d.f,ghjklzxcvb nmQAZXSWEDCVFRTGBNHYUJMKIOLP"
setlocal enabledelayedexpansion
echo !charset!
endlocal
By the way, if you want to include a literal percent, you should do it double (%%).
Hi I have this little command to copy files in a batch, which will help because I do this specific copy multiple times a day. The problem occurs while using the xcopy command. Everything is in order, but I am receiving this error: "Invalid path 0 files copied". Here is the code:
C:\Windows\System32\xcopy /Y "C:\Users\Ryan\Desktop\mmars_pub\" "C:\Users\Ryan\Desktop\Dropbox\MMARS\mmars_pub\"
I'm using the full path to the xcopy executable because I was having trouble configuring the path environment variable to function properly. I would imagine that it shouldn't affect the result though. I read somewhere about the "Prevent MS-DOS-based programs from detecting Windows" checkbox that should fix the issue, but I just can't seem to find that. Any help appreciated.
Original answer
Remove the ending backslash from the source folder path
C:\Windows\System32\xcopy.exe /Y "C:\Users\Ryan\Desktop\mmars_pub" "C:\Users\Ryan\Desktop\Dropbox\MMARS\mmars_pub\"
edited 2015/10/01
While the original question used a literal path, and the indicated solution will solve the problem, there is another option. For literal paths and in cases where the path is inside a variable and could (or not) end in a backslash, it is enough to ensure that the ending backslash (if present) is separated from the quote, including an ending dot.
xcopy /y "x:\source\." "x:\target"
xcopy /y "%myVariable%." "x:\target"
This ending dot will not interfere in files/folders names. If there is and ending backslash, the additional dot will simply refer to the same folder. If there is not ending backslash as in windows files and folders can not end their names with a dot, it will be discarded.
BUT if the output of the xcopy command will be processed, remember that this additional dot will be included in the paths shown.
note: The solutions are above the line. Keep reading if interested on why/where there is a problem.
Why xcopy "c:\source\" "d:\target\" fails but xcopy "c:\source" "d:\target\" works?
Both commands seems to have valid path references, and ... YES! both are valid path references, but there are two elements that work together to make the command fail:
the folder reference is quoted (note: it should be quoted, it is a good habit to quote paths as you never know when they will contain spaces or special characters)
xcopy is not an internal command handled by cmd but an executable file
As xcopy is an external command, its arguments are not handled following the cmd parser command line logic. They are handled by the Microsoft C startup code.
This parser follows two sets of rules, official rules
Arguments are delimited by white space, which is either a space or a tab.
A string surrounded by double quotation marks is interpreted as a single argument, regardless of white space contained within. A quoted
string can be embedded in an argument. Note that the caret (^) is not
recognized as an escape character or delimiter.
A double quotation mark preceded by a backslash, \", is interpreted as a literal double quotation mark (").
Backslashes are interpreted literally, unless they immediately precede a double quotation mark.
If an even number of backslashes is followed by a double quotation mark, then one backslash (\) is placed in the argv array for every
pair of backslashes (\\), and the double quotation mark (") is
interpreted as a string delimiter.
If an odd number of backslashes is followed by a double quotation mark, then one backslash (\) is placed in the argv array for every
pair of backslashes (\\) and the double quotation mark is interpreted
as an escape sequence by the remaining backslash, causing a literal
double quotation mark (") to be placed in argv.
and undocumented/non official rules (How Command Line Parameters Are Parsed)
Outside a double quoted block a " starts a double quoted block.
Inside a double quoted block a " followed by a different character (not another ") ends the double quoted block.
Inside a double quoted block a " followed immediately by another " (i.e. "") causes a single " to be added to the output, and the
double quoted block continues.
This parser sees the sequence \" found at the end of the "first" argument as a escaped quote that does not end/closes the argument, it is seen as part or the argument. And the "starting" quote of the "second" argument is just ending the double quoted block BUT not ending the argument, remember that arguments are delimited by white space.
So while it seems that the command line arguments are
v v v......argument delimiters
v.........v v..........v ......quoted blocks
xcopy "x:\souce\" "x:\target\"
^.......^ ^........^ ......argument data
arg #1 arg #2
arg #1 = x:\source\
arg #2 = x:\target\
the actual argument handled by xcopy is
v v .....argument delimiters
v......................v .....quoted block
xcopy "x:\souce\" "x:\target\"
^.....................^ .....argument data
arg #1
arg #1 = x:\source" x:\target"
When the ending backslash is removed or the additional dot included, the closing quote in the argument will not be escaped, it will close the quoted block and the space between arguments will be seen as a delimiter.
Can I do something like ecranning quotes in variable? For example,
if "%1"=="/?" goto :help
Will return error if argument is "
Try "%~1". The tilde modifier will strip quotes from %1, if present.
Unfortunately there is no general safe way to process strings with special chars (quotes, parentheses, caret) in batch files. There are always some cases that blow up whatever you write.