Difference in Delayed expansion of ERRORLEVEL on cmd prompt and win32_process - windows

cmd /V:ON /c dir c:\<some non existing directory> & echo %ERRORLEVEL%
Volume in drive C is PC COE Volume Serial Number is 9C37-D0B7
Directory of c:\
File Not Found
0
Lets run the same command using ! to expand the ERRORLEVEL (delayed expansion is enabled)
cmd /V:ON /c dir c:\ERt & echo !ERRORLEVEL!
Volume in drive C is PC COE
Volume Serial Number is 9C37-D0B7
Directory of c:\
File Not Found
!ERRORLEVEL!
It prints !ERRORLEVEL!.
This does work fine when I run the command using a WMI win32_process create command and proper error is returned using the !ERRORLEVEL! variable
What difference it makes when executing in a cmd prompt and executing using WMI win32_process.?

By using
cmd /V:ON /c dir c:\ERt & echo !ERRORLEVEL!
the new command process started with cmd /V:ON executes just the command dir c:\ERt and then closes and the second command echo !ERRORLEVEL! is executed by current command process on which delayed expansion is not enabled.
The command line
cmd /V:ON /c "dir c:\ERt & echo !ERRORLEVEL!"
must be used to run dir c:\ERt AND echo !ERRORLEVEL! in new command process before exiting this command process.
The double quotes around entire command line to execute in new command process makes the difference.
Without the double quotes around command line to execute in new command process the current command process interprets the line with the two commands as when typing
cmd /V:ON /c dir c:\ERt
echo !ERRORLEVEL!
Also possible would be
cmd /V:ON /c dir c:\ERt ^& echo !ERRORLEVEL!
Now & operator is escaped for current command process being interpreted as literal character and therefore the entire line is executed with caret character ^ removed by the new command process.

Related

How to make a custom "Press any key to continue" message in batch

For an example "Press any key to return to command prompt"
what do I even put here lol.
There can be used in the batch file the command line:
set /P "=Press any key to return to command prompt... " <nul & pause >nul & echo/
The caret is blinking in this case on same line as the prompt and not on the next line as it is the case on using:
echo Press any key to return to command prompt...
pause >nul
But in most cases can be simply used just pause to halt the batch file execution until the user pressed a key which is often not necessary on user executed the batch file from within a command prompt window.
There can be used the following command line to halt the batch file execution only if cmd.exe was started with option /c as first argument as done when double clicking on a batch file.
setlocal EnableExtensions EnableDelayedExpansion & for /F "tokens=1,2" %%G in ("!CMDCMDLINE!") do endlocal & if /I "%%~nG" == "cmd" if /I "%%~H" == "/c" pause
This command line does not run pause if the batch file is executed from within an opened command prompt window by a user who typed the batch file name and pressed RETURN or ENTER to execute it. It is often annoying for a user of a batch file starting it from within a command prompt window to press a key to end its execution.
To understand the commands used and how they work, open a command prompt window, execute there the following commands, and read the displayed help pages for each command, entirely and carefully.
cmd /?
echo /?
endlocal /?
for /?
help ... outputs an incomplete list of Windows commands with a brief description
pause /?
set /?
setlocal /?
See also:
A-Z index of Windows CMD commands
Single line with multiple commands using Windows batch file
Microsoft documentation about Using command redirection operators
DosTips forum topic: ECHO. FAILS to give text or blank line - Instead use ECHO/

quotes inside quotes with windows' cmd

I have the following command set as a custom URL protocol in windows registry:
cmd /V:ON /C "SET r=%1 & SET s=!r:jhvnc:=! & start C:\Program Files\uvnc bvba\UltraVNC\vncviewer.exe !s:_= !"
This is not working because the path to the exe file has a space.
Normally, I'd use quotes:
cmd /V:ON /C "SET r=%1 & SET s=!r:jhvnc:=! & start "C:\Program Files\uvnc bvba\UltraVNC\vncviewer.exe" !s:_= !"
but the command is already in quotes. I tried escaping the quotes with double quotes, but that did not work.
How can I achieve this?
Simplest work around is use the historic short folder name
That should be C:\PROGRA~1\UVNCBV~1\
check using dir /x /a:d C:\PROGRA~1\U*
cmd /V:ON /C "SET r=%1 & SET s=!r:jhvnc:=! & start C:\PROGRA~1\UVNCBV~1\UltraVNC\vncviewer.exe !s:_= !"

cmd.exe /C unable to run the command

I'm running below command which is working successfully if I run it manually via command prompt
SET filename=testfile_26032021.txt && SET newfilename=%filename:~9,8% && copy C:\test\updatedtestfile_%newfilename%.txt C:\test\updatedtestfile_%newfilename%.txt.temp
But when I run this through an external call I get an error
The system cannot find the file specified.
Here's the command I'm running
cmd.exe /C SET filename=testfile_26032021.txt && SET newfilename=%filename:~9,8% && copy C:\test\updatedtestfile_%newfilename%.txt C:\test\updatedtestfile_%newfilename%.txt.temp
I caught the error by changing the flag from /C to /K.
Any idea what is wrong with this command?
You can't do like this SET filename=testfile_26032021.txt && SET newfilename=%filename:~9,8% because %filename% is expanded at parsing time where it's not available yet. You must enable delayed expansion and tell cmd to expand the command later with !variable_name!. Besides && ends the previous command so your whole thing is parsed as 3 commands:
cmd.exe /C SET filename=testfile_26032021.txt
SET newfilename=%filename:~9,8%
copy C:\test\updatedtestfile_%newfilename%.txt C:\test\updatedtestfile_%newfilename%.txt.temp
So you must quote the command like this
cmd.exe /V:on /C "SET "filename=testfile_26032021.txt" && SET "newfilename=!filename:~9,8!" && copy C:\test\updatedtestfile_!newfilename!.txt C:\test\updatedtestfile_!newfilename!.txt.temp"
or
cmd.exe /C "setlocal enabledelayedexpansion && SET filename=testfile_26032021.txt && SET newfilename=!filename:~9,8! && copy C:\test\updatedtestfile_!newfilename!.txt C:\test\updatedtestfile_!newfilename!.txt.temp"
See also
Windows command prompt: Using a variable set in the same line of a one-liner
How set a variable and then use it in the same line in command prompt
Setting and using variable within same command line in Windows cmd.exe

How to run commands on another cmd

I want to run commands on 2 cmds while opening the same file, like if I open a .bat file It opens 2 cmd and they run 2 differents commands (1 each). It's possible to do that?
If I got you right this is what you want to do, note it's a batch file:
#echo off
start cmd /c "echo 1st command && pause"
start cmd /c "echo 2nd command && pause"
Read about cmd here and about start here. The following switches of the cmd command can be considered:
/c: Carries out the command specified by string and then stops.
/k: Carries out the command specified by string and continues.
Instead of using /k I used /c with a pause command to show the concatenation of 2 commands here.
To concate 2 commands use commandA && commandB which is described here at ss64 which is a great site when it comes to batch scripting:
commandA && commandB: Run commandA, if it succeeds then run commandB
As requested another example with cd, dir and pause could look like:
#echo off
start cmd /c "cd C:\Users\ && dir && pause"
start cmd /c "cd C:\ && dir && pause"
It changes the directory, prints the directory list and wait for use input.

%ERRORLEVEL% is not working incase multiple commands on a Single line

I am trying the below commands and want to get exit of my process(%ERRORLEVEL%). But it is returning previous(last) executed exit code result of sample.exe. I want to get exit code of current command. My requirement is to execute multiple commands in single line*(not batch script)*.
Command:
cmd /c sample.bat "test" > c:\ouput.log & echo %ERRORLEVEL% > c:\returnCode.log
I even tried using "setlocal enableDelayedExpansion" like below. Still It is not returning the exit code of current command
cmd /c setlocal enableDelayedExpansion & sample.bat "test" > c:\ouput.log & echo %ERRORLEVEL% > c:\returnCode.log
Please let me know the way to get current command's exit code.
This should work:
cmd /V:ON /c sample.exe "test" > c:\ouput.log ^& echo !ERRORLEVEL! ^> c:\returnCode.log
/V:ON switch have the same effect of setlocal EnableDelayedExpansion. For further details, type: cmd /?
EDIT: Small error fixed, the & character must be escaped with ^, otherwise, the echo !ERRORLEVEL! command is not executed in the cmd /V:ON !!!
EDIT: Escaping the echo redirection via ^> causes just that echo to be piped into the log. If you do not escape that, the entire command is piped there, i.e. including the stdout stream from "sample.exe".
cmd /c sample.exe "test" > c:\ouput.log & call echo %%ERRORLEVEL%% > c:\returnCode.log
Should work for you. See endless SO items related to delayedexpansion
Thank for your response. I am able to get the exit code of current executed command with below command, only when I run through WMI class(Win32_Process). Using WMI client, I am executing the below command on Remote machine and it is working fine i.e. able to write exit code in Retrun.txt
Command:
cmd /V:ON /c sample.bat "test" > c:\Output.txt & echo !ERRORLEVEL! > c:\Return.txt
But if I run the same command in command prompt of the same remote machine, it is printing "!ERRORLVEL!" in Return.txt instead of "sample.bat" exit code.
I am curious to know why it is not working if I run from Command prompt of the same machine locally.

Resources